home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DNet / DGoInit.cpp < prev    next >
Text File  |  1996-07-05  |  81KB  |  3,074 lines

  1. // DGopherInit.cp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include <ncbi.h>
  6. #include <dgg.h>
  7. #include <Dvibrant.h>
  8.  
  9. #include "DTCP.h"
  10. #include "DGopher.h"
  11. #include "DGoList.h"
  12. #include "DGoPlus.h"
  13. #include "DGoClasses.h"
  14. #include "DGoPrefs.h"
  15. #include <DApplication.h>
  16. #include <DDialogText.h>
  17. #include "DUtil.h"
  18. #include <DIconLib.h>
  19.  
  20. #include "DGoInit.h"
  21.  
  22.  
  23.  
  24.  
  25. enum GomapStatus {
  26.     kMapNever, kMapDefault, kMapAlways 
  27.     };
  28.     
  29. enum GoMapDataKind { 
  30.     kKindData=110, kServerTypeData, kServerSuffixData, kLocalData,
  31.     kdKindData, kdServerTypeData, kdServerSuffixData, kdLocalData,
  32.     kDontCheckDups = kdKindData
  33.     };
  34.  
  35. enum GopherHandlerKind { 
  36.     kNoHandler = 0, kInternalHandler, kExternalHandler
  37.     };
  38.     
  39. enum GoMapStatus {
  40.     kNochange, kChanged, kAdded, kDeleted
  41.     };
  42.     
  43. enum GopherInternalHandlers {
  44.     kErrHandler, kTextHandler, kFolderHandler, kFolderPlusHandler, kQueryHandler, 
  45.     kCSOHandler, kWhoisHandler, kFingerHandler, kNoteHandler, 
  46.     kPictHandler, kRTFHandler, kHTMLHandler, kMailHandler, kHTTPHandler, kImageHandler,
  47.     kGifHandler,
  48.   kNetTextHandler, kNetRTFHandler, kNetPictHandler, kNetGifHandler,
  49.     kMaxInternalHandler
  50.      };    
  51.     
  52.     // this list *must* match GopherInternalHandlers list
  53.     // in most cases, we'd just do kTextHandler = 'text', but that damn 16bitter won't let us
  54.     // also config list must use 4char ids, including spaces 
  55.  
  56.         // !! this is a DAMN weak point -- need to remember to add here when
  57.         // add new internal types 
  58.  
  59. Local char* gInternalHandlerIDs[kMaxInternalHandler+1] = {
  60.     "err ", "text", "goph", "gopl", "ques", 
  61.     "cso ", "who ", "fing", "note", 
  62.     "pict", "rtf ", "html", "mail", "http", "imag", "gif ",
  63.   "ntxt", "nrtf", "npic", "ngif",
  64.     NULL
  65.     };
  66.  
  67.  
  68.  
  69. Boolean            gNeedTypeChange = false;    // global used in DGopher & DGoList
  70.  
  71. DGopherMapList*        gGopherMap = NULL;
  72.  
  73. #if 0
  74. Local DList* gNetKinds = NULL;
  75. Local DList* gServerSuffixes = NULL;
  76. Local DList* gServerType = NULL;
  77. #endif
  78.  
  79.  
  80. Local char*    gYesNo[2]; // = { "No", "Yes" };
  81.  
  82.  
  83. Local    char* gDefaultTypes = 
  84. "goph=application/gopher-menu internet/gopher-menu\n" 
  85. "gopl=application gopher+-menu internet/gopher+-menu\n"
  86. "cso=internet/cso\n"
  87. "err=internet/error\n"
  88. "ques=internet/gopher-query\n"
  89. "who=internet/whois\n"
  90. "fing=internet/finger\n"
  91. "note=internet/gopher-note\n"
  92. "mail=internet/mail\n"
  93. "ftp =internet/ftp\n"
  94. "html=text/html internet/html\n"
  95. "text=text/plain text/-\n"
  96. "file=file/-\n"
  97. "imag=image/-\n"
  98. "gif=image/gif\n"
  99. "moov=video/-\n"
  100. "sond=audio/-\n"
  101. "teln=terminal/telnet\n"
  102. "tibm=terminal/tn3270\n"
  103. ;
  104.  
  105. Local    char* gDefaultServerTypes = 
  106. "text=    0    0    \n"
  107. "goph=    1    1    \n"
  108. "cso =    2    2 \n"
  109. "err =    3    3    \n"
  110. "hqx =    4    4 \n"
  111. "file=    5    9 \n"
  112. "file=    6    9 \n"
  113. "ques=    7    7 \n"
  114. "teln=    8    8 \n"
  115. "file=    9    9 \n"
  116. "sond=    s    s \n"
  117. "who    =    w    w \n"
  118. "imag=    I    I \n"
  119. "gif =    g    I \n"
  120. "note=    i    i \n"
  121. "tibm=    T    T \n"
  122. "html=    h    h \n"
  123. "moov=    ;    ; \n"
  124. ;
  125.  
  126. Local    char* gDefaultSuffixes = 
  127. "text=    .txt    .text    .doc\n"
  128. "post=    .ps\n"
  129. "rtf =    .rtf\n"
  130. "jpeg=    .jpg    .jpeg    .jfif\n"
  131. "gif =    .gif\n"
  132. "hqx =    .hqx\n"
  133. ;
  134.  
  135.  
  136. //[gpmap-local]
  137. //#type=    precedence    handling    MacType    MacCreator    HandlerApp
  138. // codewarrior can't deal w/ an #ifdef inside of a char data declaration 
  139.  
  140. #ifdef WIN_MAC
  141. Local    char* gDefaultLocal = 
  142. "gopl=    1    internal\n"
  143. "goph=    2    internal\n"
  144. "err=    1    internal\n"
  145. "ques=    1    internal\n"
  146. "note=    1 internal\n"
  147. "mail=    0    none\n"
  148. "ftp=    0    none\n"
  149. "cso=    0    none\n"
  150. "who=    1 internal\n"
  151. "fing=    1    internal\n"
  152. "text=    1    internal    TEXT/ttxt    TeachText\n"
  153. ;
  154.  
  155. //"html=    1    internal  TEXT/MWEB    MacWeb\n"
  156. //"pict=    1    internal    PICT/ttxt    TeachText\n"
  157. #else
  158.  
  159. Local    char* gDefaultLocal = 
  160. "gopl=    1    internal\n"
  161. "goph=    2    internal\n"
  162. "err=    1    internal\n"
  163. "ques=    1    internal\n"
  164. "note=    1 internal\n"
  165. "mail=    0    none\n"
  166. "ftp=    0    none\n"
  167. "cso=    0    none\n"
  168. "who=    1 internal\n"
  169. "fing=    1    internal\n"
  170. "text=    1    internal    .txt\n"
  171. ;
  172.  
  173. //"html=    1    internal  .html\n"
  174. //"pict=    1    internal    .pict\n"
  175. #endif
  176.  
  177.  
  178. #if 0
  179. class DMapName : public DObject
  180. {
  181. public:
  182.     long         fId;
  183.     char    * fName;
  184.     DMapName( long localid, char* name) {
  185.         fId= localid; 
  186.         fName= StrDup( name);
  187.         }
  188.     ~DMapName() { MemFree( fName); }
  189. };
  190.  
  191.  
  192. // static
  193. short dgiCompareMapNames( DMapName* a, DMapName* b)
  194. {
  195. #if 0
  196.     return ((long)a - (long)b);
  197. #else
  198.     if (a->fId == b->fId) 
  199.         return Nlm_StringCmp(a->fName, b->fName);
  200.     else 
  201.         return a->fId - b->fId;
  202. #endif
  203. #endif
  204.  
  205.  
  206.  
  207. class DGodocKindList : public DObject
  208. {
  209. public:
  210.     enum    { kNodata, kNamedata, kListdata };
  211.     char    fDatatype;
  212.     void    * fData;
  213.     
  214.     DGodocKindList() { fDatatype= kNodata; fData= NULL; }
  215.     DGodocKindList( char* name, Boolean lowercase = false) {
  216.         fDatatype= kNodata; fData= NULL;
  217.         AddName( name, lowercase);
  218.         }
  219.     ~DGodocKindList();
  220.     void AddName( char* name, Boolean lowercase = false);
  221.     const char* GetName();
  222.     void GetAllNames(char* buf, ulong maxbuf);
  223.     Boolean Match(char* name, Boolean ignorecase = false);
  224. };
  225.  
  226. DGodocKindList::~DGodocKindList() 
  227.     if (fData) {
  228.         if (fDatatype == kListdata) {
  229.             DList* dl= (DList*) fData;
  230.             long i, n= dl->GetSize();
  231.             for (i=0; i<n; i++) { DString* ds= (DString*) dl->At(i); delete ds; }
  232.             delete dl;
  233.             } 
  234.         else MemFree( fData);  
  235.         }
  236. }
  237.  
  238. const char* DGodocKindList::GetName()
  239. {
  240.     switch (fDatatype) {
  241.         case kNamedata: 
  242.             return (char*) fData;
  243.         case kListdata: {
  244.             DString* ds= (DString*) ((DList*) fData)->First();
  245.             if (ds) return ds->Get();
  246.             else return NULL;
  247.             }
  248.         default:
  249.             return NULL;
  250.         }
  251. }
  252.  
  253.  
  254. void DGodocKindList::GetAllNames(char* buf, ulong maxbuf)
  255. {
  256.     if (buf && maxbuf) 
  257.      switch (fDatatype) {
  258.         case kNamedata: 
  259.             StrNCpy( buf, (char*) fData, maxbuf);
  260.             break;
  261.             
  262.         case kListdata: {
  263.             long i, n= ((DList*)fData)->GetSize();
  264.             buf[0]= 0;
  265.             for (i= 0; i<n; i++) {
  266.                 DString* ds= (DString*) ((DList*) fData)->At(i);
  267.                 StrNCat( buf, ds->Get(), maxbuf);
  268.                 StrNCat( buf, " ", maxbuf);
  269.                 }
  270.             break;
  271.             }
  272.             
  273.         default:
  274.             buf[0]= 0;
  275.             break;
  276.         }
  277. }
  278.     
  279.     
  280. Boolean DGodocKindList::Match(char* name, Boolean ignorecase)
  281. {
  282.     switch (fDatatype) {
  283.         case kNamedata: 
  284.             if (ignorecase) 
  285.                 return (Nlm_StringICmp( (char*) fData, name) == 0);
  286.             else 
  287.                 return (Nlm_StringCmp( (char*) fData, name) == 0);
  288.                 
  289.         case kListdata: 
  290.             if (name == NULL) return false;
  291.             else {
  292.                 Boolean match;
  293.                 long i, n= ((DList*)fData)->GetSize();
  294.                 for (i= 0; i<n; i++) {
  295.                     DString* ds= (DString*) ((DList*) fData)->At(i);
  296.                     if (ignorecase) 
  297.                         match= (Nlm_StringICmp( (char*) ds->Get(), name) == 0);
  298.                     else 
  299.                         match= (Nlm_StringCmp( (char*) ds->Get(), name) == 0);
  300.                     if (match) return true;
  301.                     }
  302.                 return false;
  303.                 }
  304.             
  305.         default:
  306.             return (name == NULL);
  307.         }
  308. }
  309.  
  310.  
  311. void DGodocKindList::AddName( char* name, Boolean lowercase)
  312. {
  313.     DString* ds;
  314.     if (!name) return;
  315.     else if (!fData || fDatatype==kNodata) {
  316.         fDatatype= kNamedata;
  317.         fData= StrDup( name);
  318.         if (lowercase) StrLocase( (char*)fData);
  319.         return;
  320.         }
  321.     else if (fDatatype == kNamedata) {
  322.         ds= new DString((char*)fData);
  323.         MemFree(fData);
  324.         fDatatype= kListdata;
  325.         fData= new DList();
  326.         ((DList*) fData)->InsertLast(ds);
  327.         //goto StuffList;
  328.         }
  329.         
  330.     if (fDatatype == kListdata) {
  331. //StuffList:
  332.         DList* dl= (DList*) fData;
  333.         ds= new DString(name);
  334.          if (lowercase) StrLocase( (char*)ds->Get());
  335.         long i, n= dl->GetSize();
  336.         Boolean match= false;
  337.         for (i= 0; i<n && !match; i++) {
  338.             DString* d2= (DString*) dl->At(i);
  339.             match= (Nlm_StringCmp( (char*) d2->Get(), (char*)ds->Get()) == 0);
  340.             }
  341.         if (!match) dl->InsertLast(ds);
  342.         }
  343. }
  344.  
  345.  
  346.  
  347.         // local dialog...
  348.         
  349. class DGoMapEditView : public DCluster {        
  350. public:
  351.     DGopherMap    *    fMapper;
  352.     short        fForm;
  353.     Boolean fInstallKind;
  354.     
  355.     DGoMapEditView(long id, DView* itsSuperior, short itsForm, DGopherMap* itsMapper,
  356.             short width, short height, Boolean hidden = false, char* title = NULL);
  357.     virtual ~DGoMapEditView();
  358.     virtual void InstallControls();
  359.     virtual void Answers();
  360. };
  361.  
  362.  
  363. class DGoMapEditDlog : public DWindow 
  364. {
  365. public:
  366.     enum GoMapEditForms { kFormLocal=1, kFormServerSuffixes, kFormServerLocalMap, kFormNew };
  367.     DGopherMap            * fMapper, * fNewMapper;
  368.     DGoMapEditView    * fView;
  369.     char     * fOtherKinds;
  370.     short        fForm;
  371.      
  372.     DGoMapEditDlog(DGopherMap* itsMapper, short itsForm, 
  373.                 char* itsKind = "text/plain");
  374.     virtual ~DGoMapEditDlog();
  375.     virtual Boolean IsMyAction(DTaskMaster* action); 
  376.     virtual void OkayAction();
  377.     virtual void Open();
  378. };
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386. void NewGopherMap() 
  387. {
  388. #if 0
  389.     long i;
  390.     if (gNetKinds) {
  391.         for (i=0; i<gNetKinds->GetSize(); i++)
  392.             delete (DMapName*)gNetKinds->At(i);
  393.         delete gNetKinds;
  394.         }
  395.     gNetKinds= new DList(dgiCompareMapNames);
  396.  
  397.     if (gServerType) {
  398.         for (i=0; i<gServerType->GetSize(); i++)
  399.             delete (DMapName*)gServerType->At(i);
  400.         delete gServerType;
  401.         }
  402.     gServerType= new DList(dgiCompareMapNames);
  403.     
  404.     if (gServerSuffixes) {
  405.         for (i=0; i<gServerSuffixes->GetSize(); i++)
  406.             delete (DMapName*)gServerSuffixes->At(i);
  407.         delete gServerSuffixes;
  408.         }
  409.     gServerSuffixes= new DList(dgiCompareMapNames);
  410. #endif
  411.  
  412.     if (gGopherMap) {
  413.         gGopherMap->FreeAllObjects();
  414.         delete gGopherMap;
  415.         }
  416.     gGopherMap= new DGopherMapList();
  417. }
  418.  
  419.  
  420. void ReadGoMapPrefSection(char* section, short dataKind, char* defaultData) 
  421. {
  422.     char *sectnames, *sectend, *params, *name, *ep;
  423.     ulong sectlen;
  424.  
  425.     sectnames= gApplication->GetPrefSection(section, sectlen, NULL);  
  426.     if (sectnames) {
  427.         sectend= sectnames + sectlen;
  428.         name= sectnames;
  429.         while (name && name < sectend) {
  430.             ep= StrChr(name,'\0');
  431.             params= gApplication->GetPref( name, section, NULL);
  432.             gGopherMap->ReadParams( name, params, dataKind);  
  433.             MemFree(params);
  434.             name= ep+1;  
  435.             }
  436.         MemFree(sectnames);
  437.         }
  438.         
  439.     else if (defaultData) {
  440.         sectend= defaultData + StrLen(defaultData);
  441.         name= defaultData;
  442.         while (name && name < sectend) {
  443.             ep= StrChr(name,'\n');  
  444.             if (!ep) ep= StrChr(name,'\0');
  445.             params= StrChr(name,'=');
  446.             if (params) params++;
  447.             gGopherMap->ReadParams( name, params, dataKind);  
  448.             name= ep+1;  
  449.             }
  450.         }
  451. }
  452.  
  453.  
  454.  
  455. void StoreGopherIcons()
  456. {
  457. #if 0
  458. enum GopherIconID {
  459.     kTextIcon                = 2200,    // resource fork must have these icon/cicon 
  460.     kFolderIcon            = 2201,
  461.     kPhonebookIcon    = 2202, //CSO phonebook
  462.     kDefaultIcon        = 2203,
  463.     kBinhexIcon            = 2204,
  464.     kUuencodeIcon     = 2206,
  465.     kIndexIcon             = 2207,
  466.     kTelnetIcon            = 2208,
  467.     kSoundIcon            = 2212,
  468.     kWhoisPhonebookIcon    = 2213,
  469.     kBinaryIcon            = 2214,
  470.     kImageIcon            = 2215,
  471.     kMovieIcon            = 2216,
  472.     kHTMLIcon                = 2217,
  473.     kNoteIcon                = 2218,
  474.     kFirstIcon            = kTextIcon,
  475.     kLastIcon                = kNoteIcon
  476. };
  477. #endif
  478.  
  479. unsigned short cTextIcon[] = {
  480.  kTextIcon, 0, 32, 32, 64,
  481.  0x1fff, 0xfc00, 0x1000,  0x600, 0x1000,  0x500, 0x1000,  0x480,
  482.  0x1000,  0x440, 0x1000,  0x420, 0x1000,  0x7f0, 0x101f, 0xf810,
  483.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  484.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  485.  0x1000,   0x10, 0x101f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  486.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  487.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x1000,   0x10,
  488.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1fff, 0xfff0 
  489.   ,0,0,0,0,0,0 
  490.     };
  491.     new DIcon( (IconStore*) cTextIcon); // data is stored in gIconList
  492.  
  493. unsigned short cFolderIcon[] = {
  494.  kFolderIcon, 0, 32, 32, 64,
  495.       0,      0,      0,      0,      0,      0,      0,      0,
  496.       0,      0,      0,      0,      0,      0,  0x7f0,      0,
  497.   0x808,      0, 0x1004,      0, 0x2002,      0, 0x4001, 0xfffc,
  498.  0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2,
  499.  0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2,
  500.  0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2,
  501.  0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2,
  502.  0x8000,    0x2, 0x8000,    0x2, 0x8000,    0x2, 0xffff, 0xfffe 
  503.   ,0,0,0,0,0,0 
  504.     };
  505.     new DIcon( (IconStore*) cFolderIcon); 
  506.  
  507. unsigned short cPhonebookIcon[] = {
  508.  kPhonebookIcon, 0, 32, 32, 64,
  509.       0,      0,      0,      0,      0,      0,      0,      0,
  510.       0,      0,   0x3f, 0xfe00,  0x1ff, 0xffc0,  0x3ff, 0xffe0,
  511.   0x7ec, 0x1ff0,  0x7ef, 0xfbf0,  0x3df, 0xfde0,   0x18,  0xc00,
  512.    0x3a, 0xae00,   0x38,  0xe00,   0x7a, 0xaf00,   0x78,  0xf00,
  513.    0x7f, 0xff00,   0x7f, 0xff00,   0x7f, 0xff00,   0x60,  0x300,
  514.  0x7fff, 0xffff, 0x3fff, 0xfffe, 0x2000,    0x2, 0x3c00,    0x2,
  515.  0x2870,    0x2, 0x2021, 0xc002, 0x2000, 0x8702, 0x2000,  0x21e,
  516.  0x2000,    0xa, 0x2000,    0x2, 0x3fff, 0xfffe, 0x7fff, 0xffff 
  517.   ,0,0,0,0,0,0 
  518.     };
  519.     new DIcon( (IconStore*) cPhonebookIcon); // data is stored in gIconList
  520.  
  521. unsigned short cSoundIcon[] = {
  522.  kSoundIcon, 0, 29, 29, 54,
  523.       0,      0,      0,  0x300,      0,  0xf00,      0, 0x3f00,
  524.       0, 0xfd00,    0x3, 0xf100, 0xffff, 0xffff, 0xe003, 0x8100,
  525.  0xe002,  0x100, 0xe002,  0x100, 0xe002,  0x100, 0xffff, 0xffff,
  526.  0xe002,  0x100, 0xec02,  0x100, 0xec02,  0x700, 0xe002,  0xf00,
  527.  0xffff, 0xffff, 0xe01e, 0x1f00, 0xec3e, 0x1e00, 0xec3e, 0x1c00,
  528.  0xe03c,      0, 0xffff, 0xffff, 0xe000,      0, 0xe000,      0,
  529.  0xe000,      0, 0xe000,      0, 0xffff, 0xffff 
  530.   ,0,0,0,0,0,0 
  531.     };
  532.     new DIcon( (IconStore*) cSoundIcon);
  533.  
  534. unsigned short cBinhexIcon[] = {
  535.  kBinhexIcon, 0, 31, 31, 62,
  536.  0x1fff, 0xfc00, 0x1000,  0x600, 0x1000,  0x500, 0x1000,  0x480,
  537.  0x1000,  0x440, 0x1000,  0x420, 0x1652, 0xafb0, 0x155a, 0xa8b0,
  538.  0x155a, 0xa8f0, 0x1756, 0xee50, 0x1556, 0xa8f0, 0x1556, 0xa8b0,
  539.  0x1652, 0xaeb0, 0x1000,   0x10, 0x107e,   0x10, 0x1043,   0x10,
  540.  0x1042, 0x8010, 0x1043, 0xc010, 0x1040, 0x5010, 0x1040, 0x6810,
  541.  0x1040, 0x4410, 0x1040, 0x8210, 0x1041,  0xf10, 0x1042, 0x1190,
  542.  0x1041, 0x3d10, 0x1040, 0x8b90, 0x107f, 0xc790, 0x1000, 0x2990,
  543.  0x1000, 0x1010, 0x1000,   0x10, 0x1fff, 0xfff0 
  544.   ,0,0,0,0,0,0 
  545.     };
  546.     new DIcon( (IconStore*) cBinhexIcon);
  547.  
  548. unsigned short cDefaultIcon[] = {
  549.  kDefaultIcon, 0, 32, 32, 64,
  550.  0x1fff, 0xfc00, 0x1000,  0x600, 0x1000,  0x500, 0x1000,  0x480,
  551.  0x1000,  0x440, 0x1000,  0x420, 0x1000,  0x7f0, 0x1000,   0x10,
  552.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  553.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  554.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  555.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  556.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  557.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1fff, 0xfff0 
  558.   ,0,0,0,0,0,0 
  559.     };
  560.     new DIcon( (IconStore*) cDefaultIcon);
  561.  
  562. unsigned short cUuencodeIcon[] = {
  563.  kUuencodeIcon, 0, 31, 31, 62,
  564.  0x1fff, 0xfc00, 0x1000,  0x600, 0x1000,  0x500, 0x1000,  0x480,
  565.  0x1000,  0x440, 0x1000,  0x420, 0x1556, 0x97f0, 0x1554, 0xd490,
  566.  0x1554, 0xd490, 0x1556, 0xf490, 0x1554, 0xb490, 0x1554, 0xb490,
  567.  0x1226, 0x9670, 0x1000,   0x10, 0x107e,   0x10, 0x1043,   0x10,
  568.  0x1042, 0x8010, 0x1043, 0xc010, 0x1040, 0x5010, 0x1040, 0x6810,
  569.  0x1040, 0x4410, 0x1040, 0x8210, 0x1041,  0xf10, 0x1042, 0x1190,
  570.  0x1041, 0x3d10, 0x1040, 0x8b90, 0x107f, 0xc790, 0x1000, 0x2990,
  571.  0x1000, 0x1010, 0x1000,   0x10, 0x1fff, 0xfff0 
  572.   ,0,0,0,0,0,0 
  573.     };
  574.     new DIcon( (IconStore*) cUuencodeIcon);
  575.  
  576. unsigned short cIndexIcon[] = {
  577.  kIndexIcon, 0, 30, 30, 60,
  578.       0,      0,      0,      0, 0x3fff, 0xfffc, 0x7fff, 0xfffc,
  579.  0x7fff, 0xfffc, 0x6000,   0x1c, 0x6000,   0x1c, 0x601f, 0xc01c,
  580.  0x603f, 0xf01c, 0x607f, 0xf81c, 0x60f8, 0xfc1c, 0x60f0, 0x7c1c,
  581.  0x60f0, 0x7c1c, 0x60f0, 0x7c1c, 0x6000, 0xf81c, 0x6001, 0xf01c,
  582.  0x6003, 0xe01c, 0x6007, 0xc01c, 0x6007, 0x801c, 0x6007, 0x801c,
  583.  0x6007, 0x801c, 0x6000,   0x1c, 0x6000,   0x1c, 0x6000,   0x1c,
  584.  0x6007, 0x801c, 0x6007, 0x801c, 0x6007, 0x801c, 0x6000,   0x1c,
  585.  0x6000,   0x18, 0x3fff, 0xfff0 
  586.   ,0,0,0,0,0,0 
  587.     };
  588.     new DIcon( (IconStore*) cIndexIcon);
  589.  
  590. unsigned short cTelnetIcon[] = {
  591.  kTelnetIcon, 0, 32, 32, 64,
  592.  0x3fc0, 0x7f80, 0x2040, 0x4080, 0x2f40, 0x5e80, 0x2f40, 0x5e80,
  593.  0x2040, 0x4080, 0xfff1, 0xffe0, 0xb01f, 0x603e, 0x80f1,  0x3e2,
  594.  0xfff1, 0xffe2,      0,    0x2,   0x7f, 0xf002,   0x55, 0x5002,
  595.    0x55, 0x5002,   0x55, 0x5002,   0x55, 0x5002,   0x55, 0x5002,
  596.    0x55, 0x5002,   0x55, 0x5007,  0x3ff, 0xffff,  0x200,  0x207,
  597.   0x200,  0x202,  0x3ff, 0xfe02,      0,    0x2, 0xfe1f, 0xc3fa,
  598.  0x8210, 0x420a, 0xba17, 0x42ea, 0xba17, 0x42ee, 0xbbf7, 0x7ee8,
  599.  0x8210, 0x4208, 0xfe1f, 0xc3f8, 0x8610, 0x4208, 0xfe1f, 0xc3f8 
  600.   ,0,0,0,0,0,0 
  601.     };
  602.     new DIcon( (IconStore*) cTelnetIcon);
  603.  
  604. unsigned short cWhoisPhonebookIcon[] = {
  605.  kWhoisPhonebookIcon, 0, 32, 32, 64,
  606.       0,      0,      0,      0,      0,      0,      0,      0,
  607.       0,      0,   0x3f, 0xfe00,  0x1ff, 0xffc0,  0x3ff, 0xffe0,
  608.   0x7ec, 0x1ff0,  0x7ef, 0xfbf0,  0x3df, 0xfde0,   0x18,  0xc00,
  609.    0x3a, 0xae00,   0x38,  0xe00,   0x7a, 0xaf00,   0x78,  0xf00,
  610.    0x7f, 0xff00,   0x7f, 0xff00,   0x7f, 0xff00,   0x60,  0x300,
  611.  0x7fff, 0xffff, 0x3fff, 0xfffe, 0x2000,    0x2, 0x2000,    0x2,
  612.  0x2000,    0x2, 0x2000,    0x2, 0x2000,    0x2, 0x2000,    0x2,
  613.  0x2000,    0x2, 0x2000,    0x2, 0x3fff, 0xfffe, 0x7fff, 0xffff 
  614.   ,0,0,0,0,0,0 
  615.     };
  616.     new DIcon( (IconStore*) cWhoisPhonebookIcon);
  617.  
  618. unsigned short cBinaryIcon[] = {
  619.  kBinaryIcon, 0, 32, 32, 64,
  620.  0x1fff, 0xfc00, 0x1000,  0x600, 0x1000,  0x500, 0x1000,  0x480,
  621.  0x1000,  0x440, 0x1000,  0x420, 0x1000,  0x7f0, 0x1000,   0x10,
  622.  0x1049, 0x2410, 0x10aa, 0xaa10, 0x10aa, 0xaa10, 0x1049, 0x2410,
  623.  0x1000,   0x10, 0x1000,   0x10, 0x1092, 0x9210, 0x10aa, 0xaa10,
  624.  0x10aa, 0xaa10, 0x1092, 0x9210, 0x1000,   0x10, 0x1000,   0x10,
  625.  0x1049, 0x2410, 0x10aa, 0xaa10, 0x10aa, 0xae10, 0x1049, 0x2a10,
  626.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10,
  627.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0x1fff, 0xfff0 
  628.   ,0,0,0,0,0,0 
  629.     };
  630.     new DIcon( (IconStore*) cBinaryIcon);
  631.  
  632. unsigned short cImageIcon[] = {
  633.  kImageIcon, 0, 32, 32, 64,
  634.  0x1fff, 0xfc00, 0x1000,  0x600, 0x13a0,  0x500, 0x13a0,  0x480,
  635.  0x13a8, 0x2440, 0x13a0,  0x420, 0x13a0, 0xe7f0, 0x13a1, 0x1010,
  636.  0x13a2,  0x810, 0x13a2,  0x810, 0x13aa,  0x890, 0x13a1, 0x1010,
  637.  0x13e0, 0xe010, 0x1220,   0x10, 0x1220,   0x10, 0x1220,   0x10,
  638.  0x122b, 0xfe90, 0x1222,  0x210, 0x11c2,  0x210, 0x1322, 0x1fd0,
  639.  0x1322, 0x1050, 0x1212, 0x1050, 0x121b, 0xf250, 0x1210, 0x1050,
  640.  0x1230, 0x1050, 0x1120, 0x1fd0, 0x11a0,   0x10, 0x10e0,   0x10,
  641.  0x1230, 0x2090, 0x1000,   0x10, 0x1000,   0x10, 0x1fff, 0xfff0 
  642.   ,0,0,0,0,0,0 
  643.     };
  644.     new DIcon( (IconStore*) cImageIcon);
  645.  
  646. unsigned short cMovieIcon[] = {
  647.  kMovieIcon, 0, 32, 32, 64,
  648.  0x1fff, 0xfc00, 0x1200,  0x600, 0x1200,  0x500, 0x1e7f, 0xfc80,
  649.  0x1e7f, 0xfc40, 0x127f, 0xfc20, 0x127f, 0xfff0, 0x1e7f, 0xfcf0,
  650.  0x1e00,   0xf0, 0x1200,   0x90, 0x13ff, 0xff90, 0x1e00,   0xf0,
  651.  0x1e00,   0xf0, 0x127f, 0xfc90, 0x127f, 0xfc90, 0x1e7f, 0xfcf0,
  652.  0x1e7f, 0xfcf0, 0x127f, 0xfc90, 0x127f, 0xfc90, 0x1e00,   0xf0,
  653.  0x1e00,   0xf0, 0x13ff, 0xff90, 0x1200,   0x90, 0x1e00,   0xf0,
  654.  0x1e55, 0x54f0, 0x122a, 0xa890, 0x1255, 0x5490, 0x1e2a, 0xa8f0,
  655.  0x1e55, 0x54f0, 0x1200,   0x90, 0x1200,   0x90, 0x1fff, 0xfff0 
  656.   ,0,0,0,0,0,0 
  657.     };
  658.     new DIcon( (IconStore*) cMovieIcon);
  659.  
  660. unsigned short cHTMLIcon[] = {
  661.  kHTMLIcon, 0, 32, 32, 64,
  662.  0x1fff, 0xfe00, 0x1000,  0x300, 0x1000,  0x280, 0x101f, 0xfa40,
  663.  0x1000,  0x220, 0x107f, 0xfbf0, 0x1000,   0x10, 0x107f, 0xf810,
  664.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x101f, 0xf810,
  665.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  666.  0x1000,   0x10, 0x107f, 0xf810, 0x1000,   0x10, 0x107f, 0xf810,
  667.  0x1000,   0x10, 0x1000,   0x10, 0x1000,   0x10, 0xffff, 0xfffe,
  668.     0x8, 0x8000,  0x808, 0x8040, 0x1808, 0x8060, 0x2ff0, 0x7fd0,
  669.  0x4000,    0x8, 0x2fff, 0xffd0, 0x1800,   0x60,  0x800,   0x40 
  670.   ,0,0,0,0,0,0 
  671.     };
  672.     new DIcon( (IconStore*) cHTMLIcon);
  673.  
  674. unsigned short cNoteIcon[] = {
  675.  kNoteIcon, 0, 32, 32, 64,
  676.  0xffff, 0xffff, 0x807f, 0xffff, 0x807f, 0xffff, 0x807f, 0xffff,
  677.  0x807f, 0xffff, 0x807f, 0xc0ff, 0x887f,   0x3f, 0x887e,   0x1f,
  678.  0x887c,    0xf, 0x8078,    0x7, 0x8078,    0x7, 0x8070,    0x3,
  679.  0x8071, 0xddc3, 0x8070,    0x3, 0x8070,    0x3, 0x8071, 0xdd43,
  680.  0x8070,    0x3, 0x8070,    0x3, 0x8071, 0xd703, 0x8070,    0x3,
  681.  0x87f0,    0x3, 0x81f1, 0xeec3, 0x81f0,    0x7, 0x81f0,    0x7,
  682.  0x81f0,    0xf, 0x81e0,   0x1f, 0x8f80,   0x7f, 0x81ff, 0xffff,
  683.  0x81ff, 0xffff, 0x81ff, 0xffff, 0x81ff, 0xffff, 0xffff, 0xffff 
  684.   ,0,0,0,0,0,0 
  685.     };
  686.     new DIcon( (IconStore*) cNoteIcon);
  687.  
  688.  
  689.  
  690.     // small icons
  691. unsigned short rTextIcon[] = {
  692.  10000+kTextIcon, 0, 16, 16, 16,
  693.  0x7ff0, 0x4038, 0x402c, 0x47fc, 0x4004, 0x4fe4, 0x4004, 0x47e4,
  694.  0x4004, 0x4fe4, 0x4004, 0x4fe4, 0x4004, 0x4004, 0x4004, 0x7ffc 
  695.   ,0,0,0,0,0,0 
  696.     };
  697.     new DIcon( (IconStore*) rTextIcon);
  698.  
  699. unsigned short rFolderIcon[] = {
  700.  10000+kFolderIcon, 0, 16, 16, 16,
  701.       0,      0,      0, 0x3c00, 0x6200, 0xc1fe, 0x8001, 0x8001,
  702.  0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xffff 
  703.   ,0,0,0,0,0,0 
  704.     };
  705.     new DIcon( (IconStore*) rFolderIcon);
  706.  
  707. unsigned short rPhonebookIcon[] = {
  708.  10000+kPhonebookIcon, 0, 16, 16, 16,
  709.       0,      0,  0x7f0, 0x1ffc, 0x3ffc, 0x1ffc,  0x7f0,  0xff0,
  710.   0xff0,  0xff0, 0xffff, 0x7001, 0x4601, 0x4061, 0x4007, 0xffff 
  711.   ,0,0,0,0,0,0 
  712.     };
  713.     new DIcon( (IconStore*) rPhonebookIcon);
  714.  
  715. unsigned short rSoundIcon[] = {
  716.  10000+kSoundIcon, 0, 14, 14, 14,
  717.    0x10,   0x70,  0x1f0, 0xffff, 0xc110, 0xffff, 0xe110, 0xe130,
  718.  0xffff, 0xe770, 0xffff, 0xc000, 0xc000, 0xffff 
  719.   ,0,0,0,0,0,0 
  720.     };
  721.     new DIcon( (IconStore*) rSoundIcon);
  722.  
  723. unsigned short rBinhexIcon[] = {
  724.  10000+kBinhexIcon, 0, 16, 16, 16,
  725.  0x7ff0, 0x4008, 0x4004, 0x7ffc, 0x7ffc, 0x7fec, 0x7dfc, 0x4f04,
  726.  0x4984, 0x48e4, 0x48b4, 0x497c, 0x49fc, 0x4ffc, 0x4044, 0x7ffc 
  727.   ,0,0,0,0,0,0 
  728.     };
  729.     new DIcon( (IconStore*) rBinhexIcon);
  730.  
  731. unsigned short rDefaultIcon[] = {
  732.  10000+kDefaultIcon, 0, 16, 16, 16,
  733.  0x7ff0, 0x4038, 0x402c, 0x403c, 0x4004, 0x4004, 0x4004, 0x4004,
  734.  0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x7ffc 
  735.   ,0,0,0,0,0,0 
  736.     };
  737.     new DIcon( (IconStore*) rDefaultIcon);
  738.  
  739. unsigned short rUuencodeIcon[] = {
  740.  10000+kUuencodeIcon, 0, 16, 16, 16,
  741.  0x7ff0, 0x4038, 0x402c, 0x7ffc, 0x7fec, 0x7eec, 0x57fc, 0x4f04,
  742.  0x4984, 0x48e4, 0x48b4, 0x497c, 0x49fc, 0x4ffc, 0x4044, 0x7ffc 
  743.   ,0,0,0,0,0,0 
  744.     };
  745.     new DIcon( (IconStore*) rUuencodeIcon);
  746.  
  747. unsigned short rIndexIcon[] = {
  748.  10000+kIndexIcon, 0, 15, 15, 15,
  749.       0, 0xfffe, 0xfffe, 0xc006, 0xc7c6, 0xcc66, 0xcc66, 0xc0c6,
  750.  0xc186, 0xc106, 0xc006, 0xc006, 0xc106, 0xc006, 0xfffe 
  751.   ,0,0,0,0,0,0 
  752.     };
  753.     new DIcon( (IconStore*) rIndexIcon);
  754.  
  755. unsigned short rTelnetIcon[] = {
  756.  10000+kTelnetIcon, 0, 16, 16, 16,
  757.  0x78f8, 0x78f8, 0xfdfc, 0xffff, 0xfdfd,  0xfc1,  0xfc1,  0xfc1,
  758.   0xfc3, 0x1fff, 0x1ff1, 0xf79f, 0xf79f, 0xffff, 0xf79e, 0xf79e 
  759.   ,0,0,0,0,0,0 
  760.     };
  761.     new DIcon( (IconStore*) rTelnetIcon);
  762.  
  763. unsigned short rWhoisPhonebookIcon[] = {
  764.  10000+kWhoisPhonebookIcon, 0, 16, 16, 16,
  765.       0,      0,  0x7f0, 0x1ffc, 0x3ffc, 0x1ffc,  0x7f0,  0xff0,
  766.   0xff0,  0xff0, 0xffff,    0x1,    0x1,    0x1,    0x1, 0xffff 
  767.   ,0,0,0,0,0,0 
  768.     };
  769.     new DIcon( (IconStore*) rWhoisPhonebookIcon);
  770.  
  771. unsigned short rBinaryIcon[] = {
  772.  10000+kBinaryIcon, 0, 16, 16, 16,
  773.  0x7ff0, 0x4038, 0x402c, 0x403c, 0x4ff4, 0x4ff4, 0x4004, 0x4ff4,
  774.  0x4ff4, 0x4004, 0x4ff4, 0x4ff4, 0x4004, 0x4004, 0x4004, 0x7ffc 
  775.   ,0,0,0,0,0,0 
  776.     };
  777.     new DIcon( (IconStore*) rBinaryIcon);
  778.  
  779. unsigned short rImageIcon[] = {
  780.  10000+kImageIcon, 0, 16, 16, 16,
  781.  0x7ff0, 0x5c38, 0x5c2c, 0x5dfc, 0x5d24, 0x5d64, 0x5cc4, 0x5404,
  782.  0x55f4, 0x5d7c, 0x554c, 0x55dc, 0x5474, 0x5c04, 0x4404, 0x7ffc 
  783.   ,0,0,0,0,0,0 
  784.     };
  785.     new DIcon( (IconStore*) rImageIcon);
  786.  
  787. unsigned short rMovieIcon[] = {
  788.  10000+kMovieIcon, 0, 16, 16, 16,
  789.  0x7fe0, 0x7030, 0x57e8, 0x77fc, 0x5014, 0x7ffc, 0x5014, 0x77dc,
  790.  0x57d4, 0x77dc, 0x5014, 0x7ffc, 0x5014, 0x755c, 0x5014, 0x7ffc 
  791.   ,0,0,0,0,0,0 
  792.     };
  793.     new DIcon( (IconStore*) rMovieIcon);
  794.  
  795. unsigned short rHTMLIcon[] = {
  796.  10000+kHTMLIcon, 0, 16, 16, 16,
  797.  0x7ff0, 0x4038, 0x47fc, 0x4fe4, 0x4fe4, 0x47e4, 0x4fe4, 0x4fe4,
  798.  0x4fe4, 0x4fe4, 0x4004, 0xffff, 0x2288, 0x7efc, 0xfffe, 0x600c 
  799.   ,0,0,0,0,0,0 
  800.     };
  801.     new DIcon( (IconStore*) rHTMLIcon);
  802.  
  803. unsigned short rNoteIcon[] = {
  804.  10000+kNoteIcon, 0, 16, 16, 16,
  805.  0xffff, 0x8fff, 0x8fff, 0xaf07, 0xae03, 0x8e03, 0x8df9, 0x8df9,
  806.  0x8c01, 0x8df1, 0xbdf9, 0x9c03, 0x9c07, 0xbfff, 0x9fff, 0xffff 
  807.   ,0,0,0,0,0,0 
  808.     };
  809.     new DIcon( (IconStore*) rNoteIcon);
  810.  
  811.  
  812.  
  813.  
  814.  
  815.     // tiny icons
  816.  
  817. unsigned short sTextIcon[] = {
  818.  20000+kTextIcon, 0, 13, 13, 12,
  819.  0xff00, 0x8180, 0x81c0, 0xbe40, 0x8040, 0xbe40, 0x8040, 0xbe40,
  820.  0x8040, 0xbe40, 0x8040, 0xffc0 
  821.   ,0,0,0,0,0,0 
  822.     };
  823.     new DIcon( (IconStore*) sTextIcon);
  824.  
  825. unsigned short sFolderIcon[] = {
  826.  20000+kFolderIcon, 0, 12, 12, 10,
  827.  0x3800, 0x4400, 0x83f0, 0x8010, 0x8010, 0x8010, 0x8010, 0x8010,
  828.  0x8010, 0xfff0 
  829.   ,0,0,0,0,0,0 
  830.     };
  831.     new DIcon( (IconStore*) sFolderIcon);
  832.  
  833. unsigned short sPhonebookIcon[] = {
  834.  20000+kPhonebookIcon, 0, 12, 12, 10,
  835.  0x7f80, 0xffc0, 0x7f80, 0x3f00, 0x3f00, 0xffe0, 0x8020, 0x8020,
  836.  0x8020, 0xffe0 
  837.   ,0,0,0,0,0,0 
  838.     };
  839.     new DIcon( (IconStore*) sPhonebookIcon);
  840.  
  841. unsigned short sSoundIcon[] = {
  842.  20000+kSoundIcon, 0, 13, 13, 12,
  843.  0xff00, 0x8180, 0x81c0, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040,
  844.  0x8040, 0x8040, 0x8040, 0xffc0 
  845.   ,0,0,0,0,0,0 
  846.     };
  847.     new DIcon( (IconStore*) sSoundIcon);
  848.  
  849. unsigned short sBinhexIcon[] = {
  850.  20000+kBinhexIcon, 0, 13, 13, 12,
  851.  0xff00, 0x8180, 0x81c0, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040,
  852.  0x8040, 0x8040, 0x8040, 0xffc0 
  853.   ,0,0,0,0,0,0 
  854.     };
  855.     new DIcon( (IconStore*) sBinhexIcon);
  856.  
  857. unsigned short sDefaultIcon[] = {
  858.  20000+kDefaultIcon, 0, 13, 13, 11,
  859.  0xfff0, 0x8030, 0x9e30, 0xb330, 0xb330, 0x8230, 0x8c30, 0x8c30,
  860.  0x8c30, 0x8030, 0xffe0 
  861.   ,0,0,0,0,0,0 
  862.     };
  863.     new DIcon( (IconStore*) sDefaultIcon);
  864.  
  865. unsigned short sUuencodeIcon[] = {
  866.  20000+kUuencodeIcon, 0, 13, 13, 12,
  867.  0x7f80, 0xbf40, 0xfec0, 0xf8c0, 0xf0c0, 0xf8c0, 0xffc0, 0x8040,
  868.  0x8740, 0x8040, 0xffc0, 0x4080 
  869.   ,0,0,0,0,0,0 
  870.     };
  871.     new DIcon( (IconStore*) sUuencodeIcon);
  872.  
  873. unsigned short sIndexIcon[] = {
  874.  20000+kIndexIcon, 0, 13, 13, 11,
  875.    0x80,  0x380, 0xfff0, 0x8480, 0xe4b0, 0x8480, 0xedb0, 0x8d80,
  876.  0xe030, 0x8000, 0xfff0 
  877.   ,0,0,0,0,0,0 
  878.     };
  879.     new DIcon( (IconStore*) sIndexIcon);
  880.  
  881. unsigned short sTelnetIcon[] = {
  882.  20000+kTelnetIcon, 0, 12, 12, 10,
  883.  0x7f80, 0xffc0, 0x7f80, 0x3f00, 0x3f00, 0xffe0, 0x8020, 0x8020,
  884.  0x8020, 0xffe0 
  885.   ,0,0,0,0,0,0 
  886.     };
  887.     new DIcon( (IconStore*) sTelnetIcon);
  888.  
  889. unsigned short sWhoisPhonebookIcon[] = {
  890.  20000+kWhoisPhonebookIcon, 0, 13, 13, 12,
  891.  0xff00, 0x8180, 0x81c0, 0x9040, 0xa840, 0xa840, 0x9240, 0x8240,
  892.  0x8240, 0x8240, 0x8040, 0xffc0 
  893.   ,0,0,0,0,0,0 
  894.     };
  895.     new DIcon( (IconStore*) sWhoisPhonebookIcon);
  896.  
  897. unsigned short sBinaryIcon[] = {
  898.  20000+kBinaryIcon, 0, 13, 13, 12,
  899.  0xff00, 0x8180, 0x81c0, 0x8040, 0x8040, 0x8040, 0x8040, 0x8040,
  900.  0x8040, 0x8040, 0x8040, 0xffc0 
  901.   ,0,0,0,0,0,0 
  902.     };
  903.     new DIcon( (IconStore*) sBinaryIcon);
  904.  
  905. unsigned short sImageIcon[] = {
  906.  20000+kImageIcon, 0, 13, 13, 12,
  907.  0xff00, 0xb180, 0xb1c0, 0xb640, 0xb640, 0xb040, 0xb040, 0x8240,
  908.  0xb740, 0xb240, 0x9040, 0xffc0 
  909.   ,0,0,0,0,0,0 
  910.     };
  911.     new DIcon( (IconStore*) sImageIcon);
  912.  
  913. unsigned short sMovieIcon[] = {
  914.  20000+kMovieIcon, 0, 13, 13, 12,
  915.  0xff00, 0xbf80, 0xe1c0, 0xe1c0, 0xbf40, 0xe1c0, 0xe1c0, 0xbf40,
  916.  0xe1c0, 0xe1c0, 0xbf40, 0xffc0 
  917.   ,0,0,0,0,0,0 
  918.     };
  919.     new DIcon( (IconStore*) sMovieIcon);
  920.  
  921. unsigned short sHTMLIcon[] = {
  922.  20000+kHTMLIcon, 0, 14, 14, 14,
  923.  0xff00, 0x8180, 0x9fc0, 0xbf40, 0x9f40, 0xbf40, 0xbf40, 0x8040,
  924.  0xffc0,  0xc00, 0x4c80, 0xffc0, 0x4080, 0x0000 
  925.   ,0,0,0,0,0,0 
  926.     };
  927.     new DIcon( (IconStore*) sHTMLIcon);
  928.  
  929. unsigned short sNoteIcon[] = {
  930.  20000+kNoteIcon, 0, 13, 13, 12,
  931.  0xfff0, 0x8ff0, 0x8e30, 0xac30, 0x8d90, 0x8c10, 0x8dd0, 0x9c10,
  932.  0x9d90, 0xb030, 0x9ff0, 0xfff0 
  933.   ,0,0,0,0,0,0 
  934.     };
  935.     new DIcon( (IconStore*) sNoteIcon);
  936. }
  937.  
  938.  
  939. void InitializeUGopher()
  940. {
  941.         // this should be flexible enough for other oses, default is "gmap-local"
  942.         char* kLocalMapSection= "gpmap-local";
  943. #ifdef WIN_MAC
  944.         kLocalMapSection = "gpmap-local-mac";
  945. #endif
  946. #ifdef OS_UNIX
  947.         kLocalMapSection = "gpmap-local-unix";
  948. #endif
  949. #ifdef OS_DOS
  950.         kLocalMapSection = "gpmap-local-msdos";
  951. #endif
  952.  
  953.             // call from app.inits 
  954.     gDoSuffix2MacMap= false;
  955.     gNeedTypeChange= false;
  956.     gGopherMap = NULL;
  957.     gYesNo[false]= "No";
  958.     gYesNo[true ]= "Yes";
  959.  
  960.     NewGopherMap();
  961.  
  962.     ReadGoMapPrefSection("gpmap-types", kdKindData, gDefaultTypes);
  963.     ReadGoMapPrefSection("gpmap-gopher0", kdServerTypeData, gDefaultServerTypes);
  964.     ReadGoMapPrefSection("gpmap-server-suffix", kdServerSuffixData, gDefaultSuffixes);
  965.     ReadGoMapPrefSection(kLocalMapSection, kdLocalData, gDefaultLocal);
  966.     ReadGoMapPrefSection("gpmap-local", kdLocalData, NULL);
  967.  
  968.     gGopherIconID= kDefaultIcon;
  969.   StoreGopherIcons();
  970.     gGopherIcons= gIconList;     // is this what we want??
  971.     gIconSize= 2;                         // need to read in some app prefs  
  972. }
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979. // DGopherMap ------------------------------
  980.  
  981.  
  982. DGopherMap::DGopherMap()
  983. {
  984.     Initialize();
  985. }
  986.  
  987. DGopherMap::~DGopherMap()
  988. {
  989.     MemFree(fSuffix); 
  990.     MemFree(fHandlerName); 
  991.     MemFree(fParameters); 
  992. //DGodocKindList    
  993.     if (fKind) delete fKind; 
  994.     if (fServerSuffixes) delete fServerSuffixes; 
  995. }
  996.  
  997. Boolean DGopherMap::suicide(void) 
  998.     if (GetOwnerCount() <= 1) { 
  999.         delete this; 
  1000.         return true; 
  1001.         }
  1002.     else 
  1003.         return DObject::suicide();
  1004. }
  1005.  
  1006. Boolean DGopherMap::suicide(short ownercount)
  1007. {
  1008.     if (ownercount < 1) {
  1009.         delete this; 
  1010.         return true; 
  1011.         }
  1012.     else 
  1013.         return DObject::suicide(ownercount);
  1014. }
  1015.  
  1016. void DGopherMap::Initialize()
  1017. {
  1018.     fId= 0;
  1019.     fHandlerType= kNoHandler;
  1020.     fKind = new DGodocKindList();
  1021.     fPreference= 0;
  1022.     fTransferType= kTransferBinary; 
  1023.     fServerSuffixes= NULL;
  1024.     fHandlerName= NULL;
  1025.     fParameters= NULL;
  1026.     fSuffix= NULL;
  1027. #ifdef WIN_MAC
  1028.     fMacType= '\?\?\?\?';  
  1029.     fMacSire= '\?\?\?\?';
  1030. #else
  1031.         // damn 16bit os/compiler won't understand 'abcd' as a long
  1032.     fMacType= fMacSire= 0;
  1033. #endif
  1034.     fLocalType = '0';      
  1035.     fServerType = '0';      
  1036.     fMapSuffixWhen= kMapNever; 
  1037.     fSaveToDisk= false;
  1038.     fCommand= DGopher::cNewGopherFile;
  1039.     fStatus= kNochange;
  1040.     fServerLocalChanged= false;
  1041.     fServerSuffixesChanged= false;
  1042. }
  1043.  
  1044.  
  1045.  
  1046. void DGopherMap::ReadData(short datakind)
  1047. {
  1048.     switch (datakind) {
  1049.         case kdKindData:
  1050.         case kKindData:
  1051.              ReadKind(); 
  1052.              break;
  1053.         case kdServerTypeData: 
  1054.         case kServerTypeData: 
  1055.             ReadServerType(); 
  1056.             break;
  1057.         case kdServerSuffixData: 
  1058.         case kServerSuffixData:
  1059.             ReadServerSuffix(); 
  1060.             break;
  1061.         case kdLocalData: 
  1062.         case kLocalData: 
  1063.             ReadLocalHandling(); 
  1064.             break;
  1065.         }
  1066. }
  1067.  
  1068.  
  1069. void DGopherMap::ReadKind()
  1070. {
  1071.     const    char* wordbreaks = " \t\r\n";
  1072.     char     *word;
  1073. #if 1    
  1074.     //line format: "text/plain text/anykind text/unknown text/jive"
  1075.     word= strtok( fParameters, wordbreaks); 
  1076.     while (word) {
  1077.         if (!fKind) fKind= new DGodocKindList(word, true);
  1078.         else fKind->AddName(word, true);
  1079.         word= strtok( NULL, wordbreaks); 
  1080.         }
  1081. #else
  1082.     //line format: "text/plain text"
  1083.     word= strtok( fParameters, wordbreaks); if (!word) return; 
  1084.     SetKind(word); 
  1085.     word= strtok( NULL, wordbreaks); if (!word) return; 
  1086.     SetTransferBinary( to_lower(*word) != 't');
  1087. #endif
  1088. }
  1089.  
  1090.  
  1091. void DGopherMap::ReadServerType()
  1092. {
  1093.     //line format: "0    0"
  1094.     const    char* wordbreaks = " \t\r\n";
  1095.     char     *word;
  1096.     
  1097.     word= strtok( fParameters, wordbreaks); if (!word) return; 
  1098.     SetServerType( word); //fServerType= *word;
  1099.     word= strtok( NULL, wordbreaks); if (!word) return; 
  1100.     SetLocalType( word); //fLocalType= *word;
  1101. }
  1102.  
  1103.  
  1104. void DGopherMap::ReadServerSuffix()
  1105. {
  1106.     //line format: " .txt    .text    .doc"
  1107.     const    char* wordbreaks = " \t\r\n";
  1108.     char     *word;
  1109.     
  1110.     word= strtok( fParameters, wordbreaks); 
  1111.     while (word) {
  1112. #if 1
  1113.         if (!fServerSuffixes) fServerSuffixes= new DGodocKindList(word);
  1114.         else fServerSuffixes->AddName(word);
  1115. #else
  1116.         if (!gServerSuffixes) gServerSuffixes= new DList(dgiCompareMapNames,DList::kDeleteObjects);
  1117.         DMapName* aStr= new DMapName( fId, word);
  1118.         gServerSuffixes->InsertLast( aStr);
  1119. #endif
  1120.         word= strtok( NULL, wordbreaks); 
  1121.         }
  1122. }
  1123.  
  1124.  
  1125. void DGopherMap::ReadLocalHandling()
  1126. {
  1127.     const    char* wordbreaks = " \t\r\n";
  1128.     char     *word;
  1129.     short    num;
  1130.     
  1131.     word= strtok( fParameters, wordbreaks); if (!word) return; 
  1132.     SetPreference(word);
  1133.  
  1134.     word= strtok( NULL, wordbreaks); if (!word) return; 
  1135.     SetTransferBinary( to_lower(*word) != 't');
  1136.  
  1137.     word= strtok( NULL, wordbreaks); if (!word) return; 
  1138.     SetHandlerType( word);
  1139.     
  1140.     //Mac    line format: "rtf = 2    text   launch        TEXT/MSWD    'MicroSoft Word'"
  1141.     //msdos  line format: "rtf = 0    text   launch    .rtf    appname.exe"
  1142.     //unix   line format: "gif = 1    binary launch    .gif    'xv $file'"
  1143.     word= strtok( NULL, wordbreaks);  if (!word) return; 
  1144.     SetSuffix(word);
  1145.  
  1146.     if (word) {
  1147.         // all oses -- last param is fHandlerName string
  1148.         // need to watch for names w/ embedded spaces, etc -- look for ' and " delimiters  
  1149.         char* namebreaks;
  1150.         char* cp= word + StrLen(word) + 1;
  1151.         while (cp && *cp && isspace(*cp)) cp++;
  1152.         if (*cp == '"') namebreaks = "\"\r\n";
  1153.         else if (*cp == '\'') namebreaks = "\'\r\n";
  1154.         else namebreaks = " \t\r\n";
  1155.         word= strtok( cp, namebreaks);  
  1156.         if (word) SetHandlerName(word);    
  1157.         }
  1158. }
  1159.  
  1160.  
  1161. void DGopherMap::SetParameters( char* params)
  1162. {
  1163.     if (fParameters) MemFree(fParameters);
  1164.     if (params) fParameters= StrDup( (char*) params);
  1165.     else fParameters= NULL;
  1166. }
  1167.  
  1168. const char* DGopherMap::GetParameters()
  1169. {
  1170.     return fParameters;
  1171. }
  1172.  
  1173.  
  1174.  
  1175.  
  1176. void DGopherMap::SetCommand()
  1177. {
  1178.     fCommand= GetCommand();
  1179. }
  1180.  
  1181. short    DGopherMap::GetCommand()
  1182. {
  1183.     if (fHandlerType == kInternalHandler)
  1184.         switch (fId) {
  1185.                     // ?? don't really need all these, just map "text/html" to internal "text"!
  1186.   
  1187.             case kNetTextHandler:
  1188.             case kNetRTFHandler:
  1189.             case kNetPictHandler:
  1190.             case kNetGifHandler:    return DGopher::cGopherNetDoc;
  1191.  
  1192.             case kPictHandler:
  1193.             case kGifHandler:
  1194.             case kRTFHandler:
  1195.             case kHTMLHandler:
  1196.             case kMailHandler:
  1197.             case kHTTPHandler:
  1198.             case kFingerHandler    :
  1199.             case kWhoisHandler    :
  1200.             case kTextHandler        :    return DGopher::cNewGopherText;
  1201.  
  1202.             case kImageHandler    :    return DGopher::cNewGopherImage;
  1203.  
  1204.             case kCSOHandler        :
  1205.             case kQueryHandler    :
  1206.             case kFolderPlusHandler:
  1207.             case kFolderHandler    :    return DGopher::cNewGopherFolder;
  1208.             
  1209.             default:
  1210.             case kNoteHandler        : 
  1211.             case kErrHandler        : return DGopher::cNoCommand;
  1212.             }
  1213.     else 
  1214.         return DGopher::cNewGopherFile;
  1215. }
  1216.  
  1217.  
  1218. #if 0
  1219. short DGopherMap::GetHandlerType()
  1220. {
  1221.     return fHandlerType;
  1222. }
  1223. #endif
  1224.  
  1225. const char* DGopherMap::GetHandlerType()
  1226. {
  1227.     switch (fHandlerType) {
  1228.         case kInternalHandler    : return "Internal";
  1229.         case kExternalHandler    : return "External";
  1230.         default:
  1231.         case kNoHandler                : return "None";
  1232.         }
  1233. }
  1234.  
  1235. void DGopherMap::SetHandlerType( char* s)
  1236. {
  1237.         // internal, external==launch, none, ???
  1238.     if (s) switch (*s) {
  1239.         case 'i':
  1240.         case 'I': fHandlerType= kInternalHandler; break;
  1241.         case 'e':
  1242.         case 'E':  
  1243.         case 'l':
  1244.         case 'L': fHandlerType= kExternalHandler;  break;
  1245.         case 'n':
  1246.         case 'N':  
  1247.         default : fHandlerType= kNoHandler;  break;
  1248.         }
  1249. }
  1250.  
  1251.     
  1252. const char* DGopherMap::GetLocalType()
  1253. {
  1254.     static char s[2]; 
  1255.     s[0]= fLocalType;
  1256.     s[1]= 0;
  1257.     return s;
  1258. }
  1259.  
  1260. void DGopherMap::SetLocalType( char* s)
  1261. {
  1262.     if (s) fLocalType= s[0];
  1263. }
  1264.  
  1265. const char* DGopherMap::GetServerType()
  1266. {
  1267. #if 0
  1268.     long i, n= gServerType->GetSize();
  1269.     for (i=0; i<n; i++) {
  1270.         DMapName* stype= (DMapName*) gServerType->At(i);
  1271.         if (stype && stype->fId == fId)
  1272.             return stype->fName;
  1273.         }
  1274.     return NULL;
  1275. #else
  1276.     static char s[2]; 
  1277.     s[0]= fServerType;
  1278.     s[1]= 0;
  1279.     return s;
  1280. #endif
  1281. }
  1282.  
  1283.  
  1284. void DGopherMap::SetServerType( char* s)
  1285. {
  1286. #if 0
  1287.     if (!gServerType) gServerType= new DList(dgiCompareMapNames,DList::kDeleteObjects);
  1288.     DMapName* kind= new DMapName( fId, s);
  1289.     //if (!gServerType->GetEqualItemNo(kind)) //<< requires special DList compare func
  1290.     gServerType->InsertLast( kind);
  1291. #else
  1292.     if (s) fServerType= s[0];
  1293. #endif
  1294. }
  1295.  
  1296. const char* DGopherMap::GetMapWhen()
  1297. {
  1298.     switch (fMapSuffixWhen) {
  1299.         case kMapAlways    : return "Always";  
  1300.         case kMapDefault: return "Default";
  1301.         default:
  1302.         case kMapNever     : return "Never";
  1303.         }
  1304. }
  1305.  
  1306. void DGopherMap::SetMapWhen(char* when)
  1307. {
  1308.     if (when) switch (*when) {
  1309.         case 'a':
  1310.         case 'A': fMapSuffixWhen= kMapAlways; break;
  1311.         case 'd':
  1312.         case 'D': fMapSuffixWhen= kMapDefault; break;
  1313.         default : fMapSuffixWhen= kMapNever; break;
  1314.         }
  1315. }
  1316.  
  1317.  
  1318. void DGopherMap::SetSaveToDisk(Boolean turnon) 
  1319.     fSaveToDisk= turnon;
  1320. }
  1321.  
  1322. Boolean DGopherMap::GetSaveToDisk()
  1323. {
  1324.     //??
  1325.     return  (fHandlerType != kInternalHandler || fSaveToDisk); 
  1326. }
  1327.  
  1328. Boolean DGopherMap::GetTransferBinary() 
  1329.     return (fTransferType == kTransferBinary);
  1330. }
  1331.  
  1332. void DGopherMap::SetTransferBinary(Boolean turnon) 
  1333.     if (turnon) fTransferType = kTransferBinary;
  1334.     else fTransferType = kTransferText; 
  1335. }
  1336.  
  1337.  
  1338. Boolean DGopherMap::GetDisplay()
  1339. {
  1340.     return  (fHandlerType == kInternalHandler); 
  1341. }
  1342.  
  1343.  
  1344. Boolean DGopherMap::Map(DGopher* aGopher)
  1345. {
  1346.     Boolean changedtype= false;
  1347.     aGopher->fMacType= fMacType;  
  1348.     aGopher->fMacSire= fMacSire;
  1349.     aGopher->fSaveToDisk= fSaveToDisk;
  1350.     aGopher->fLaunch= (fHandlerType == kExternalHandler);
  1351.     aGopher->fCommand= GetCommand();
  1352.     short oldtt= aGopher->fTransferType;
  1353.     aGopher->fTransferType= fTransferType;
  1354.     
  1355.   if (aGopher->fType != kTypeQuery) { //?? do we always want to do this ?
  1356.         changedtype= (aGopher->fType != fLocalType);
  1357.         aGopher->fType= fLocalType;
  1358.         }
  1359.  
  1360.     if (oldtt != fTransferType)
  1361.       switch (fTransferType) {
  1362.         case kTransferBinary:  
  1363.             aGopher->SwapPathType('0','9');
  1364.             break;
  1365.         case kTransferText:  
  1366.             aGopher->SwapPathType('9','0');
  1367.             break;
  1368.         }                    
  1369.     return changedtype;
  1370. }
  1371.  
  1372.  
  1373. const char* DGopherMap::GetID() 
  1374.     if (fHandlerType == kInternalHandler && (fId>=0 && fId < kMaxInternalHandler))
  1375.         return gInternalHandlerIDs[fId];
  1376.     else
  1377.         return Idtype2Str(fId);
  1378. }
  1379.  
  1380. void DGopherMap::SetID( char* s)
  1381. {
  1382.     char sid[5];
  1383.     short i;
  1384.     for (i=0; i<4; i++) if (s[i]<' ') sid[i]=' '; else sid[i]= s[i];
  1385.     sid[4]= 0;
  1386.   for ( i= 0; i<kMaxInternalHandler; i++) 
  1387.       if (StrNCmp(sid, gInternalHandlerIDs[i], 4) == 0) {
  1388.           fId= i;
  1389.           fHandlerType= kInternalHandler;
  1390.           return;
  1391.           }
  1392.     fId= Str2Idtype(sid);
  1393.     if (fHandlerType==kInternalHandler) fHandlerType= kNoHandler;
  1394. }
  1395.  
  1396.  
  1397. const char* DGopherMap::GetMacTypeNSire() 
  1398.     // "TEXT/R*ch",  "WDBN/MSWD", "APPL/IGo4"
  1399.     static char typensire[10];
  1400.     StrNCpy(typensire, Idtype2Str(fMacType), 4);
  1401.     typensire[4]= '/';
  1402.     StrNCpy(typensire+5, Idtype2Str(fMacSire), 4);
  1403.     typensire[9]= 0;
  1404.     return typensire;
  1405. }
  1406.  
  1407. void DGopherMap::SetMacTypeNSire( char* s)
  1408. {
  1409.     // "TEXT/R*ch",  "WDBN/MSWD", "APPL/IGo4"
  1410.     if (s) {
  1411.         fMacType= Str2Idtype( s);
  1412.         if (StrLen(s) > 5) fMacSire= Str2Idtype( s+5);
  1413.         }
  1414. }
  1415.  
  1416.  
  1417. const char* DGopherMap::GetSuffix()
  1418. {
  1419. #ifdef WIN_MAC
  1420.     return GetMacTypeNSire();
  1421. #else
  1422.     return  fSuffix; 
  1423. #endif
  1424. }
  1425.  
  1426. void DGopherMap::SetSuffix( char* s)
  1427. {
  1428. #ifdef WIN_MAC
  1429.     SetMacTypeNSire(s);
  1430. #else
  1431.     if (fSuffix) MemFree(fSuffix);
  1432.     fSuffix= StrDup(s);
  1433. #endif
  1434. }
  1435.  
  1436.  
  1437. const char* DGopherMap::GetServerSuffixes()
  1438. {
  1439.         // FIX LATER
  1440.  
  1441.     return  NULL; 
  1442. }
  1443.  
  1444. void DGopherMap::SetServerSuffixes( char* s)
  1445. {
  1446.         // FIX LATER
  1447. }
  1448.  
  1449.  
  1450. const char* DGopherMap::GetKind()
  1451. {
  1452.     if (fStatus == kDeleted) return "*** DELETED ***";
  1453. #if 1
  1454.     else if (fKind) return fKind->GetName();
  1455.     else return "type/unknown";
  1456. #else
  1457.     else if (gNetKinds) {
  1458.         long i, n= gNetKinds->GetSize();
  1459.         for (i=0; i<n; i++) {
  1460.             DMapName* kind= (DMapName*) gNetKinds->At(i);
  1461.             if (kind->fId == fId) return kind->fName;
  1462.             }
  1463.         }
  1464.     return "type/unknown";
  1465. #endif
  1466. }
  1467.  
  1468. void DGopherMap::SetKind( char* s)
  1469. {
  1470. #if 1
  1471.     const    char* wordbreaks = " \t\r\n";
  1472.     char     *word;
  1473.     s= StrDup(s);
  1474.     word= strtok( s, wordbreaks); 
  1475.     while (word) {
  1476.         if (!fKind) fKind= new DGodocKindList(word, true);
  1477.         else fKind->AddName(word, true);
  1478.         word= strtok( NULL, wordbreaks); 
  1479.         }
  1480.     MemFree(s);
  1481.     
  1482. #else
  1483. #if 1
  1484.     if (!gNetKinds) gNetKinds= new DList(dgiCompareMapNames,DList::kDeleteObjects);
  1485.     DMapName* kind= new DMapName( fId, s);
  1486.     StrLocase(kind->fName);
  1487.     //if (!gNetKinds->GetEqualItemNo(kind)) //<< requires special DList compare func
  1488.     long i, n= gNetKinds->GetSize();
  1489.     for (i= 0; i<n; i++) {
  1490.         DMapName* old= (DMapName*) gNetKinds->At(i);
  1491.         if (Nlm_StringCmp(kind->fName, old->fName)==0) {
  1492.             old->fId= fId;
  1493.             return;
  1494.             }
  1495.         }
  1496.     gNetKinds->InsertLast( kind);
  1497. #else
  1498.     if (fKind) {
  1499.         // ?? assume fKind is primary kind, and s is alternate name
  1500.         //MemFree(fKind);
  1501.         if (fAltKind) MemFree(fAltKind);
  1502.         fAltKind= StrDup(s);
  1503.         StrLocase(fAltKind);
  1504.         }
  1505.     else {
  1506.         fKind= StrDup(s);
  1507.         StrLocase(fKind);
  1508.         }
  1509. #endif
  1510. #endif
  1511. }
  1512.  
  1513. const char* DGopherMap::GetHandlerName()
  1514. {
  1515.     return fHandlerName;  
  1516. }
  1517.  
  1518. void DGopherMap::SetHandlerName( char* s)
  1519. {
  1520.     if (fHandlerName) MemFree(fHandlerName);
  1521.     fHandlerName= StrDup(s);
  1522.     //StrLocase(fHandlerName);
  1523. }
  1524.  
  1525. const char* DGopherMap::GetPreference()
  1526. {
  1527.     static char snum[40]; 
  1528.     Dgg_LongToStr( fPreference, snum, 0, 40);
  1529.     return snum;
  1530. }
  1531.  
  1532. void DGopherMap::SetPreference( char* s)
  1533. {
  1534.     fPreference = atol( s);  
  1535. }
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542. // DGopherMapList ------------------
  1543.  
  1544.  
  1545. DGopherMapList::DGopherMapList() :
  1546.     DList(NULL,DList::kDeleteObjects)
  1547. {
  1548. }
  1549.  
  1550.  
  1551. void DGopherMapList::DeleteItem(char* theId)
  1552. {
  1553.     DGopherMap* mapper= new DGopherMap();
  1554.         if (mapper) {
  1555.         mapper->SetID( theId);
  1556.         long i, n= this->GetSize();
  1557.         for (i= 0; i<n; i++) {
  1558.             DGopherMap* current= this->GopherMapAt(i);
  1559.             if (current && mapper->fId == current->fId) {
  1560.                 if (current->fStatus == kDeleted) current->fStatus= kNochange;  
  1561.                 else current->fStatus= kDeleted; 
  1562.                 //this->AtDelete(i); // this deletes the current object 
  1563.                 break;
  1564.                 }
  1565.             }
  1566.         delete mapper;
  1567.         }
  1568. }
  1569.  
  1570. void DGopherMapList::ReadParams(char* theId, char* params, short datakind)
  1571. {
  1572.     DGopherMap* mapper= new DGopherMap();
  1573.     if (mapper) {
  1574.         mapper->SetID( theId);
  1575.         
  1576.         if (true) { // (datakind < kDontCheckDups) 
  1577.             long i, n= this->GetSize();
  1578.             for (i= 0; i<n; i++) {
  1579.                 DGopherMap* current= this->GopherMapAt(i);
  1580.                 if (current && mapper->fId == current->fId) {
  1581.                     current->SetParameters(params);
  1582.                     current->ReadData(datakind);
  1583.                     delete mapper;
  1584.                     return;
  1585.                     }
  1586.                 }
  1587.             }
  1588.         mapper->SetParameters(params);
  1589.         mapper->ReadData(datakind);
  1590.         this->InsertLast( mapper);
  1591.         }
  1592. }
  1593.  
  1594.  
  1595. DGopherMap* DGopherMapList::MatchHandlerKind(unsigned short& lastrank, char* aKind)
  1596. {
  1597.     Boolean okay, gotKind, gotHand;
  1598. #if 1
  1599.     long i, n= this->GetSize();
  1600.     for (i= 0; i<n; i++) {
  1601.         DGopherMap* mapper= this->GopherMapAt(i);
  1602.         gotKind= (mapper->fKind) ? mapper->fKind->Match(aKind) : false;
  1603.         if (gotKind && mapper->fPreference) {
  1604.             lastrank= mapper->fPreference;
  1605.             return mapper;
  1606.             }        
  1607.         }
  1608. #else
  1609. #if 1
  1610.     long i, n= gNetKinds->GetSize();
  1611.     for (i= 0; i<n; i++) {
  1612.         DMapName* kind= (DMapName*) gNetKinds->At(i);
  1613.         if (kind && Nlm_StringCmp(kind->fName,aKind) == 0) {
  1614.             DGopherMap* mapper= this->MatchID( kind->fId);
  1615.             if (mapper && mapper->fPreference > lastrank) {
  1616.                 lastrank= mapper->fPreference;
  1617.                 return mapper;
  1618.                 }
  1619.              }
  1620.         }
  1621. #else    
  1622.     long i, n= this->GetSize();
  1623.     for (i= 0; i<n; i++) {
  1624.         DGopherMap* mapper= this->GopherMapAt(i);
  1625.         gotKind= (mapper->fKind) ? 
  1626.             Nlm_StringCmp(mapper->fKind,aKind) == 0 : false;
  1627.         if (!gotKind) gotKind= (mapper->fAltKind) ? 
  1628.                 Nlm_StringCmp(mapper->fAltKind,aKind) == 0 : false;
  1629.         okay= gotKind;
  1630.         unsigned short rank= mapper->fPreference;
  1631.         if (okay) okay= (rank > lastrank);
  1632.         if (okay) {
  1633.             lastrank= rank;
  1634.             return mapper;
  1635.             }
  1636.         }
  1637. #endif
  1638. #endif
  1639.     return NULL;
  1640. }
  1641.  
  1642. DGopherMap* DGopherMapList::MatchHandlerKind(DGopher* aGopher)
  1643.     // need to decide which criteria to match on ...
  1644.     if (aGopher->fViews && (aGopher->fViews->GetSize()>0)) {
  1645.         unsigned short lastrank = 0;
  1646.         short choice= aGopher->fViewchoice;
  1647.         if (choice) {
  1648.             DGopherItemView* giv= (DGopherItemView*) aGopher->fViews->At(choice-1);
  1649.             if (giv) {
  1650.                 char* aKind = StrDup(giv->Kind()); 
  1651.                 StrLocase(aKind);
  1652.                 char* cp= StrChr(aKind,' '); if (cp) *cp= 0;
  1653.                     // add Language match !?!!
  1654.                 DGopherMap* result= this->MatchHandlerKind( lastrank, aKind); 
  1655.                 MemFree( aKind);
  1656.                 return result;
  1657.                 }
  1658.             else return NULL;
  1659.             }
  1660.             
  1661.         else { // stroll thru this map, look for prefered match to aGopher->fViews...
  1662.             short maxchoice= aGopher->fViews->GetSize();
  1663.             DGopherMap* bestmapper = NULL;
  1664.             for (choice = 1; choice <= maxchoice; choice++) {
  1665.                 DGopherItemView* giv= (DGopherItemView*) aGopher->fViews->At(choice-1);
  1666.                 if (giv) {
  1667.                     char* aKind = StrDup(giv->Kind()); 
  1668.                     StrLocase(aKind);                     
  1669.                     char* cp= StrChr(aKind,' '); if (cp) *cp= 0;
  1670.                     DGopherMap* amapper= this->MatchHandlerKind( lastrank, aKind); 
  1671.                     if (amapper) bestmapper= amapper;
  1672.                     MemFree( aKind);
  1673.                     }
  1674.                 }
  1675.             return bestmapper;
  1676.             }
  1677.         }
  1678.     return NULL;
  1679. }
  1680.  
  1681. DGopherMap* DGopherMapList::MatchID( long theId)
  1682.     long i, n= this->GetSize();
  1683.     for (i= 0; i<n; i++) {
  1684.         DGopherMap* mapper= this->GopherMapAt(i);
  1685.         if (theId == mapper->fId)    return mapper;
  1686.         }
  1687.     return NULL;
  1688. }
  1689.  
  1690.  
  1691. DGopherMap* DGopherMapList::MatchGopherType( char theType, Boolean matchAny)
  1692. #if 0
  1693.   if (gServerType) {
  1694.       long i, n= gServerType->GetSize();
  1695.         for (i= 0; i<n; i++) {
  1696.             DMapName* stype= (DMapName*) gServerType->At(i);
  1697.             if (stype && *stype->fName == theType) {
  1698.                 DGopherMap* mapper= this->MatchID( stype->fId);
  1699.                 if (mapper && (matchAny || mapper->fMapSuffixWhen == kMapAlways))
  1700.                     return mapper;
  1701.                 else
  1702.                     return NULL;
  1703.                 }
  1704.             }
  1705.       }
  1706. #else
  1707.     long i, n= this->GetSize();
  1708.     for (i= 0; i<n; i++) {
  1709.         DGopherMap* mapper= this->GopherMapAt(i);
  1710.         if (theType == mapper->fServerType &&
  1711.             (matchAny || mapper->fMapSuffixWhen == kMapAlways))
  1712.                             //  ^^^^^^^^^^^^^ NEED TO CHANGE TO ANOTHER FIELD, e.g. fMapServerTypeWhen 
  1713.             return mapper;
  1714.         }
  1715. #endif
  1716.     return NULL;
  1717. }
  1718.  
  1719.  
  1720. DGopherMap* DGopherMapList::MatchGopherType(DGopher* aGopher)
  1721.     return MatchGopherType( aGopher->fType, false);
  1722. }
  1723.  
  1724.  
  1725.  
  1726. DGopherMap* DGopherMapList::MatchSuffix(const char* pathname, char gopherType)
  1727.             ///  FIX THIS LATER
  1728. #if 0
  1729.     char* suffix= StrRChr( pathname, '.');
  1730.     if (!suffix) suffix= (char*) pathname;
  1731.     long i, n= gServerSuffixes->GetSize();
  1732.     for (i= 0; i<n; i++) {
  1733.         DMapName* kind= (DMapName*) gServerSuffixes->At(i);
  1734.         if (kind && Nlm_StringCmp(kind->fName,suffix) == 0) {
  1735.             DGopherMap* mapper= this->MatchID( kind->fId);
  1736.             if (mapper && (mapper->fMapSuffixWhen == kMapAlways)
  1737.              || (mapper->fMapSuffixWhen == kMapDefault && gopherType == kTypeFile))
  1738.                     return mapper;
  1739.              }
  1740.         }
  1741. #endif
  1742.     return NULL;
  1743. }
  1744.  
  1745.  
  1746. DGopherMap* DGopherMapList::MatchSuffix(DGopher* aGopher)
  1747.     return MatchSuffix( aGopher->GetPath(), aGopher->fType);
  1748. }
  1749.  
  1750.  
  1751.  
  1752.  
  1753. DGopherMap* DGopherMapList::GetPreferedFiletype(char* aKind, 
  1754.                              long& macFileType, long& macCreator, char*& suffix)
  1755. {
  1756.     unsigned short lastrank = 0;
  1757.     DGopherMap* gmap = NULL;
  1758.     aKind= StrDup(aKind);
  1759.     StrLocase(aKind);
  1760.     char* cp= StrChr(aKind,' '); if (cp) *cp= 0;
  1761.     gmap= this->MatchHandlerKind( lastrank, aKind);
  1762.     MemFree(aKind);
  1763.     
  1764.     if (gmap) {
  1765.         macFileType= gmap->fMacType;
  1766.         macCreator = gmap->fMacSire;
  1767.         suffix= StrDup(gmap->GetSuffix());
  1768.         return gmap;
  1769.         }
  1770.     else 
  1771.         return NULL;
  1772. }
  1773.  
  1774.  
  1775. DGopherMap* DGopherMapList::GetPreferedFiletype(DGopher* aGopher, 
  1776.                              long& macFileType, long& macCreator, char*& suffix)
  1777. {
  1778.     unsigned short lastrank = 0;
  1779.     DGopherMap* gmap = NULL;
  1780.     if (!aGopher) return false;
  1781.     char* aKind= StrDup(aGopher->GetViewChoiceKind());
  1782.     if (aKind) {
  1783.         StrLocase(aKind);
  1784.         char* cp= StrChr(aKind,' '); if (cp) *cp= 0;
  1785.         gmap= this->MatchHandlerKind( lastrank, aKind);
  1786.         MemFree(aKind);
  1787.         }
  1788.     if (!gmap) 
  1789.         gmap= this->MatchGopherType( aGopher->fType, true);
  1790.     if (gmap) {
  1791.         macFileType= gmap->fMacType;
  1792.         macCreator = gmap->fMacSire;
  1793.         suffix= StrDup(gmap->GetSuffix());
  1794.             //?? do we want to set these in caller's data !?
  1795.         //aGopher->fMacType= macFileType;
  1796.         //aGopher->fMacSire= macCreator;
  1797.         //aGopher->fLaunch= (gmap->fHandlerType == kExternalHandler);
  1798.         return gmap;
  1799.         }
  1800.     else 
  1801.         return NULL;
  1802. }
  1803.  
  1804.             
  1805.     
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816. //class DGoMapHandlerView : public DTableView
  1817.  
  1818. enum GoDocMessages {
  1819.     kEditButHit = 4560, kAddButHit, kRemoveButHit, 
  1820.     kServerTypeEnableHit, kServerTypeButHit,
  1821.     kServerSuffixEnableHit,kServerSuffixButHit
  1822.     };
  1823.  
  1824. Local char*    kGopherTypeExample= "application/gopher+-menu";
  1825. Local char*    kGopherHandlerExample= "MicroSoft Excel 1234567890";
  1826.  
  1827.  
  1828. DGoMapHandlerView::DGoMapHandlerView(long id, DGopherMapDoc* itsDoc, 
  1829.                                                 short pixwidth, short pixheight):
  1830.     DTableView( id, itsDoc, pixwidth, pixheight, 10, 2, 50, 20, true, false),
  1831.     fItems(NULL),
  1832.     fDoc(itsDoc)
  1833. {    
  1834.     fItems= itsDoc->fItems;
  1835.     this->SetSlateBorder(true); 
  1836.     this->SetResize( DView::relsuper, DView::relsuper);
  1837.     this->SetTableFont(gGoviewFont);
  1838.     this->GetReadyToShow(); // ??
  1839. }
  1840.  
  1841.  
  1842. void DGoMapHandlerView::Drag(Nlm_PoinT mouse)
  1843. {
  1844.     // this is called on drag, if click/release are ignored
  1845.     //short row, col;
  1846.     //PointToCell(mouse, row, col);
  1847.     DTableView::Drag(mouse);
  1848. }
  1849.  
  1850. void DGoMapHandlerView::Hold(Nlm_PoinT mouse)
  1851. {
  1852.     //short row, col;
  1853.     //PointToCell(mouse, row, col);
  1854.     DTableView::Hold(mouse);
  1855. }
  1856.  
  1857. void DGoMapHandlerView::Release(Nlm_PoinT mouse)
  1858. {
  1859.     //short row, col;
  1860.     //PointToCell(mouse, row, col);
  1861.     DTableView::Release(mouse);
  1862. }
  1863.  
  1864. void DGoMapHandlerView::DoubleClickAt(short row, short col)
  1865. {
  1866.     DGopherMap* ag= fItems->GopherMapAt(row); 
  1867.     //if (ag) Message(MSG_OK, "Click on '%s'", (char*)ag->GetName());
  1868.     //if (gKeys->option()) itsViewchoice= DGopher::kGetItemInfo;  
  1869.     if (ag) fDoc->EditLocalHandling(ag, DGoMapEditDlog::kFormLocal);
  1870. }
  1871.  
  1872. void DGoMapHandlerView::SingleClickAt(short row, short col)
  1873. {
  1874.     DTableView::SingleClickAt(row,  col);
  1875. }
  1876.  
  1877.  
  1878. DGopherMap* DGoMapHandlerView::SelectedMapper()
  1879. {
  1880.     if (GetSelectedRow() != kNoSelection) 
  1881.         return fItems->GopherMapAt( GetSelectedRow());
  1882.     else 
  1883.         return NULL;
  1884. }
  1885.  
  1886.  
  1887. void DGoMapHandlerView::GetReadyToShow()
  1888. {
  1889.      //Nlm_WindoW w= Nlm_SavePort( GetNlmObject());
  1890.     SelectFont();
  1891.     short charheight= Nlm_FontHeight();
  1892.     if (fItems && fItems->GetSize() > 0) SetTableSize( fItems->GetSize(), GetMaxCols());
  1893.     SetItemHeight(0, GetMaxRows(), charheight);
  1894.  
  1895. #if THIS_IS_DONE_IN_DOC
  1896.     short  wid;
  1897.     wid= Nlm_StringWidth(kGopherTypeExample);
  1898.     this->SetItemWidth( 0, 1, wid);
  1899. #if 0     
  1900.     wid= Nlm_StringWidth("999");
  1901.     this->SetItemWidth( 1, 1, wid);  
  1902. #endif
  1903.     wid= Nlm_StringWidth(kGopherHandlerExample);
  1904.     this->SetItemWidth( 1, 1, wid);      
  1905. #endif
  1906.     
  1907.     //Nlm_RestorePort( w);
  1908. }
  1909.  
  1910. void DGoMapHandlerView::DrawCell(Nlm_RecT r, short row, short col)
  1911. {
  1912.     // need a DTableView field to handle cell rect insets !
  1913.     char *name;
  1914.     if (col) r.left += 2; // quick fix for cells against each
  1915.     DGopherMap* mp= fItems->GopherMapAt(row); 
  1916.     if (mp) switch (col) {
  1917.         case 0:  
  1918.             Nlm_DrawString(&r, (char*)mp->GetKind(), 'l', false);
  1919.             break;   
  1920.         case 1: 
  1921. #if 0 
  1922.             Nlm_DrawString(&r, (char*)mp->GetPreference(), 'l', false);
  1923.             break;   
  1924.         case 2: 
  1925. #endif 
  1926.             name= (char*)mp->GetHandlerType();
  1927.             if (*name=='E') name=(char*)mp->GetHandlerName();
  1928.             Nlm_DrawString(&r, name, 'l', false);
  1929.             break;   
  1930.         }
  1931. }
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939. // DGopherMapDoc ------------------------
  1940.  
  1941.  
  1942. DGopherMapDoc::DGopherMapDoc( long id, DGopherMapList* itsMappers) :
  1943.     DWindow(id, gApplication),
  1944.     fListView(NULL),
  1945.     fServerTypeEnable(NULL),
  1946.     fServerSuffixEnable(NULL),
  1947.     fChanged(false),
  1948.     fItems(itsMappers)  // itsMappers == gGopherMap always ??
  1949.     short width= -1, height= -1, left= -10, top= -20; // default window loc
  1950.     this->InitWindow(document, width, height, left, top, "Gopher Type Handling"); 
  1951. }
  1952.  
  1953.  
  1954. //static
  1955. void DGopherMapDoc::UpdateGopherMap(short item, DGopherMap *gm)
  1956. {
  1957.     char    name[20], buf[512], *s2, *fmt;
  1958.  
  1959.     switch (gm->fStatus) {
  1960.  
  1961.         case kChanged:
  1962.         case kAdded:
  1963.             StrNCpy(name, (char*)gm->GetID(), 20);
  1964.             gm->fKind->GetAllNames( buf, sizeof(buf));
  1965.             gApplication->SetPref( buf, name, "gpmap-types");
  1966.             s2= (char*)gm->GetHandlerName();
  1967.             if (StrChr( s2, ' ') != NULL ) {
  1968.                 if (StrChr( s2, '\'') != NULL ) fmt= "%s %s %s \"%s\"";
  1969.                 else fmt= "%s %s %s %s '%s'";
  1970.                 }
  1971.             else
  1972.                 fmt= "%s %s %s %s %s";
  1973.                 
  1974.             if (!gm->GetTransferBinary()) s2= "text"; else s2= "binary";
  1975.             sprintf(buf, fmt,
  1976.                     (char*)gm->GetPreference(), 
  1977.                     s2,
  1978.                     (char*)gm->GetHandlerType(),
  1979.                     (char*)gm->GetSuffix(),
  1980.                     (char*)gm->GetHandlerName()
  1981.                     );
  1982.             gApplication->SetPref( buf,  name, "gpmap-local");
  1983.  
  1984.                 // !! set this only if requested !!
  1985.             if (gm->fServerLocalChanged) {
  1986.                 sprintf( buf, " %c %c", *(gm->GetServerType()), *(gm->GetLocalType()));
  1987.                 gApplication->SetPref( buf,  name, "gpmap-gopher0");
  1988.                 gm->fServerLocalChanged= false;
  1989.                 }
  1990.                 // !! set this only if requested !!
  1991.             if (gm->fServerSuffixesChanged) {
  1992.                 gApplication->SetPref( (char*)gm->GetServerSuffixes(), name, "gpmap-server-suffix");
  1993.                 gm->fServerSuffixesChanged= false;
  1994.                 }
  1995.             
  1996.             gm->fStatus= kNochange;
  1997.             break;
  1998.             
  1999.         case kDeleted: 
  2000.             StrNCpy(name, (char*)gm->GetID(), 20);
  2001.             gApplication->SetPref( (char*)NULL, name, "gpmap-types");
  2002.             gApplication->SetPref( (char*)NULL, name, "gpmap-gopher0");
  2003.             gApplication->SetPref( (char*)NULL, name, "gpmap-server-suffix");
  2004.             gApplication->SetPref( (char*)NULL, name, "gpmap-local");
  2005.             if (item>kEmptyIndex) gGopherMap->AtDelete(item); //fItems
  2006.             break;
  2007.         }
  2008. }
  2009.  
  2010.  
  2011. void DGopherMapDoc::Close()
  2012. {
  2013.     if (fChanged) {
  2014.         // save all mappers to disk? -- need to track deleted/changed/added for this
  2015.         long i, n= fItems->GetSize();
  2016.         for (i=0; i<n; i++) UpdateGopherMap( i, fItems->GopherMapAt(i));
  2017.         }
  2018.         
  2019.     DWindow::Close();
  2020. }
  2021.  
  2022.  
  2023. void DGopherMapDoc::Open()
  2024. {
  2025.     DView * super;
  2026.     DButton * butt;
  2027.      DCluster * clu;
  2028.     DPrompt* pr;
  2029.     short  wid,col1wid,col2wid,height;
  2030.  
  2031.     super= this;
  2032.      Nlm_SelectFont(gGoviewFont);
  2033.     col1wid= Nlm_StringWidth(kGopherTypeExample);
  2034.     pr= new DPrompt(0,super,"Net Document Type", col1wid, 0, gGoviewFont);
  2035.     super->NextSubviewToRight();
  2036.     
  2037.     col2wid= Nlm_StringWidth(kGopherHandlerExample);
  2038.     pr= new DPrompt(0,super,"Handler", col2wid, 0, gGoviewFont);
  2039.     super->NextSubviewBelowLeft();
  2040.     
  2041.     // DGoMapHandlerView goes here...
  2042.     wid= col1wid + col2wid + 10;
  2043.     height= Nlm_FontHeight() * 10;
  2044.     fListView= new DGoMapHandlerView(0,this,wid,height);
  2045.     fListView->SetItemWidth( 0, 1, col1wid);
  2046.     fListView->SetItemWidth( 1, 1, col2wid);
  2047.  
  2048.     super= this;
  2049.     super->NextSubviewBelowLeft();
  2050.     Nlm_PoinT nps;
  2051.     this->GetNextPosition( &nps);
  2052.   nps.y += 8; // view border is cut off by buttons
  2053.     this->SetNextPosition( nps);
  2054.     butt= new DButton(kEditButHit,super,"Edit");
  2055.     butt->SetResize( DView::moveinsuper, DView::moveinsuper);
  2056.     super->NextSubviewToRight();
  2057.     butt= new DButton(kAddButHit,super,"Add");
  2058.     butt->SetResize( DView::moveinsuper, DView::moveinsuper);
  2059.     super->NextSubviewToRight();
  2060.     butt= new DButton(kRemoveButHit,super,"Remove");
  2061.     butt->SetResize( DView::moveinsuper, DView::moveinsuper);
  2062.     super->NextSubviewBelowLeft();
  2063.  
  2064. #if 0
  2065.     fServerTypeEnable= new DCheckBox(kServerTypeEnableHit,super,"Use Server-Local Gopher0 map");
  2066.     fServerTypeEnable->SetStatus(gDoSuffix2MacMap);
  2067.     fServerTypeEnable->SetResize( DView::moveinsuper, DView::moveinsuper);
  2068.  
  2069.     fServerSuffixEnable= new DCheckBox(kServerSuffixEnableHit,super,"Use Server suffix map");
  2070.     fServerSuffixEnable->SetStatus(gDoSuffix2MacMap);
  2071.     fServerSuffixEnable->SetResize( DView::moveinsuper, DView::moveinsuper);
  2072.     
  2073. #else    
  2074.     clu= new DCluster( 0, super, 0, 0, false,"Server-Local type map");
  2075.     clu->SetResize( DView::moveinsuper, DView::moveinsuper);
  2076.     super= clu;  
  2077.     fServerTypeEnable= new DCheckBox(kServerTypeEnableHit,super,"Enable");
  2078.     fServerTypeEnable->SetStatus(gDoSuffix2MacMap);
  2079.     super->NextSubviewToRight();
  2080.     butt= new DButton(kServerTypeButHit,super,"Edit map");
  2081.     //if (!gDoSuffix2MacMap) butt->Disable();
  2082.  
  2083.     super= this;
  2084.     super->NextSubviewToRight();
  2085.  
  2086.     clu= new DCluster( 0, super, 0, 0, false,"Server suffix map");
  2087.     clu->SetResize( DView::moveinsuper, DView::moveinsuper);
  2088.     super= clu;  
  2089.     fServerSuffixEnable= new DCheckBox(kServerSuffixEnableHit,super,"Enable");
  2090.     fServerSuffixEnable->SetStatus(gDoSuffix2MacMap);
  2091.     super->NextSubviewToRight();
  2092.     butt= new DButton(kServerSuffixButHit,super,"Edit map");
  2093.     //if (!gDoSuffix2MacMap) butt->Disable();
  2094. #endif
  2095.     
  2096.     super= this;         
  2097.  
  2098.     AddOkayCancelButtons();
  2099.     DWindow::Open();
  2100. }
  2101.  
  2102.  
  2103. //static
  2104. Boolean DGopherMapDoc::EditHandler( char* itsKind, DGopherMap* item, short dlogKind)
  2105. {
  2106.     Boolean didEdit= false;
  2107.     if (gGopherMap && (item || dlogKind == DGoMapEditDlog::kFormNew)) {
  2108.         DGoMapEditDlog* dlg= new DGoMapEditDlog( item, dlogKind, itsKind);
  2109.         if ( dlg->PoseModally() ) {
  2110.             item= dlg->fMapper;
  2111.             if (item->fStatus == kAdded) {
  2112.                 // must add to list & also add line to listview...
  2113.                 item->newOwner();
  2114.                 item->fStatus = kChanged; // ?? otherwise edits cause new inserts !?
  2115.                 gGopherMap->InsertLast(item); // fItems->
  2116.                 //fListView->ChangeRowSize( fListView->GetMaxRows(), 1);
  2117.                 }
  2118.             //fListView->Invalidate();
  2119.             if (dlogKind == DGoMapEditDlog::kFormServerSuffixes)
  2120.                 item->fServerSuffixesChanged= true;
  2121.             else if (dlogKind == DGoMapEditDlog::kFormServerLocalMap)
  2122.                 item->fServerLocalChanged= true;
  2123.             DGopherMapDoc::UpdateGopherMap( kEmptyIndex, item); //fChanged= true;
  2124.             didEdit= true;
  2125.             }
  2126.         delete dlg; 
  2127.         }
  2128.     return didEdit;
  2129. }
  2130.  
  2131.  
  2132. void DGopherMapDoc::EditLocalHandling(DGopherMap* item, short dlogKind)
  2133. {
  2134.     if ( item || dlogKind == DGoMapEditDlog::kFormNew) {
  2135.         DGoMapEditDlog* dlg= new DGoMapEditDlog(item, dlogKind);
  2136.         if ( dlg->PoseModally() ) {
  2137.             item= dlg->fMapper;
  2138.             if (item->fStatus == kAdded) {
  2139.                 // must add to list & also add line to listview...
  2140.                 item->newOwner();
  2141.                 item->fStatus = kChanged; // ?? otherwise edits cause new inserts !?
  2142.                 fItems->InsertLast(item);  
  2143.                 fListView->ChangeRowSize( fListView->GetMaxRows(), 1);
  2144.                 }
  2145.             fListView->Invalidate();
  2146.             fChanged= true;
  2147.             if (dlogKind == DGoMapEditDlog::kFormServerSuffixes)
  2148.                 item->fServerSuffixesChanged= true;
  2149.             else if (dlogKind == DGoMapEditDlog::kFormServerLocalMap)
  2150.                 item->fServerLocalChanged= true;
  2151.             }
  2152.         delete dlg; 
  2153.         }
  2154. }
  2155.  
  2156.  
  2157.  
  2158. Boolean DGopherMapDoc::IsMyAction(DTaskMaster* action) 
  2159. {
  2160.     DGopherMap* mapper;
  2161.     DGoMapEditDlog* dlg;
  2162.     
  2163.     switch (action->Id()) {
  2164.         case kEditButHit:
  2165.             EditLocalHandling( fListView->SelectedMapper(), DGoMapEditDlog::kFormLocal);
  2166.             return true;
  2167.             
  2168.         case kAddButHit:
  2169.             EditLocalHandling( NULL, DGoMapEditDlog::kFormNew);
  2170.             return true;
  2171.         
  2172.         case kRemoveButHit:
  2173.             mapper= fListView->SelectedMapper();
  2174.             if (mapper) {
  2175.                 fItems->DeleteItem( (char*)mapper->GetID());
  2176.                 fListView->Invalidate();
  2177.                 fChanged= true;
  2178.                 }
  2179.             return true;
  2180.         
  2181.         case kServerTypeButHit:
  2182.             EditLocalHandling( fListView->SelectedMapper(), DGoMapEditDlog::kFormServerLocalMap);
  2183.             return true;
  2184.             
  2185.         case kServerSuffixButHit:
  2186.             EditLocalHandling( fListView->SelectedMapper(), DGoMapEditDlog::kFormServerSuffixes);
  2187.           return true;
  2188.  
  2189.         case kServerTypeEnableHit:
  2190.         case kServerSuffixEnableHit:
  2191.           return true;
  2192.           
  2193.         default: 
  2194.             return DWindow::IsMyAction(action);        
  2195.         }
  2196. }
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202. void EditGopherMap()
  2203. {
  2204.     if (gGopherMap) {
  2205.         DGopherMapDoc* doc= new DGopherMapDoc(0, gGopherMap);
  2206.         doc->Open();
  2207.         }
  2208. }
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216. #if FIX_LATER
  2217.  
  2218.  
  2219. Boolean DGopherMapView::IsMyAction(DTaskMaster* action) 
  2220. {
  2221.     
  2222.   if (action->Id() == 'appn') {
  2223.         // do nonStandardFileGet('APPL') -- search for Appl signature & doc types 
  2224.         // in chosen appl rez fork
  2225.         // stuff Sire & Type
  2226.         //call this for special sfget dialog... need to have application handle specially
  2227.  
  2228. #if FIX_LATER
  2229.         const short    cChooseAppType = 4322; // this is in UGopherApp.cp
  2230.         TList * aFileList = NULL;
  2231.         if (gHasAppleEvents && gApplication->ChooseDocument(cChooseAppType, &aFileList)) {
  2232.             CStr63    aName;
  2233.             TEditText * et;
  2234.             TButton   * bt;
  2235.             TPopup    * pop;
  2236.             TView        * super = ((TView*) source)->fSuperView;
  2237.             TFile        * aFile= (TFile*) aFileList->First();
  2238.             long        sire, sig, kind= '\?\?\?\?';
  2239.             short        err, bundlecount;
  2240.             
  2241.             err= aFile->GetFileCreator(sire);
  2242.             if (et= (TEditText*) super->FindSubview('sire')) {
  2243.                 et->SetTitle( CStr31( (long)sire), kDontRedraw);
  2244.                 et->ForceRedraw();
  2245.                 }
  2246.             aFile->GetName( aName);
  2247.             if (bt= (TButton*) super->FindSubview('appn')) {
  2248.                 bt->SetTitle( aName, kDontRedraw);
  2249.                 bt->ForceRedraw();
  2250.                 }
  2251.  
  2252.             BNDLptr bundles= ReadBundle( aFile, sig, bundlecount);
  2253.             if (bundles) {         //&& sig == sire)  
  2254.                 if (pop= (TPopup*) super->FindSubview('ptyp')) {
  2255.                     kind=  SetupTypeMenu( pop, fDefaultTypes, bundles, bundlecount);
  2256.                     if (et= (TEditText*) super->FindSubview('type')) {
  2257.                         et->SetTitle( CStr31((long) kind), kDontRedraw);
  2258.                         et->ForceRedraw();
  2259.                         }
  2260.                     }
  2261.                 }
  2262.             if (bundles) free(bundles); // made w/ malloc
  2263.             aFile = (TFile *)FreeIfObject(aFile);
  2264.             aFileList = (TList *)(FreeIfObject(aFileList));
  2265.             }
  2266. #endif
  2267.         return true;
  2268.         }
  2269.         
  2270.   else if (action->Id() == 'ptyp') {
  2271.         char  aName[256];
  2272.         DEditText * et;
  2273.         DPopupList * pop = (DPopupList*) action;
  2274.         DView * super = ((DView*) action)->fSuperior;
  2275.         pop->GetItemTitle(pop->GetValue(), aName, 255);
  2276.         if (strlen(aName) > 4) aname[4]= 0;
  2277.         if (et= (DEditText*) super->FindSubview('type')) {
  2278.             et->SetTitle( aName);
  2279.             //et->ForceRedraw();
  2280.             }
  2281.         return true;
  2282.         }
  2283.         
  2284.     else
  2285.         return Inherited::IsMyAction(action);
  2286. }
  2287.  
  2288.  
  2289.  
  2290. #endif // FIX_LATER
  2291.  
  2292.  
  2293.         
  2294.                         
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301. // DGopherEditWindow ------------------------
  2302.  
  2303.  
  2304. enum DGopherEditCmds {
  2305.     citem=1,cProto,cTITL,cHOST,cPATH,cKIND,ctran,cisGp,cPORT,ctype,csire, cURL
  2306.     };
  2307.  
  2308.  
  2309. DGopherEditWindow::DGopherEditWindow(DGopher* itsGopher, Boolean editAll) :
  2310.     DWindow( 0, NULL, DWindow::fixed, -10, -10, -50, -20, NULL, kDontFreeOnClose),
  2311.     fEditAll(editAll),
  2312.     fView(NULL),
  2313.     fGopher(itsGopher)
  2314. {    
  2315.     if (fGopher && fGopher->fType != kTypeError) {
  2316.         fGopher->newOwner();
  2317.         if (fEditAll) this->SetTitle("Edit network link");
  2318.         else this->SetTitle("Open network service");
  2319.         fName= fGopher->GetName();
  2320.         fHost= fGopher->GetHost();
  2321.         fPort= fGopher->GetPort();
  2322.         fPath= fGopher->GetPath();
  2323.         fURL= fGopher->GetURL();
  2324.         }
  2325.     else {
  2326.         if (fEditAll) this->SetTitle("New network link");
  2327.         else this->SetTitle("New network service");
  2328.         fName= "Title of link";
  2329.         fHost= "Host.Name.Goes.Here";
  2330.         fPort= "70";
  2331.         fPath= "";    
  2332.         fURL= "gopher://host.name.here/00path/to/doc/here";
  2333.         }
  2334. }
  2335.  
  2336. DGopherEditWindow::~DGopherEditWindow()
  2337. {
  2338.     //if (fView) delete fView; //NNNNNOOOOOOOOO --- DView::deletesubviews does this now
  2339.     if (fGopher) fGopher->suicide();
  2340. }
  2341.  
  2342. void DGopherEditWindow::OkayAction()
  2343. {
  2344.     fView->Answers();
  2345. }
  2346.  
  2347.  
  2348. void DGopherEditWindow::Open()
  2349. {
  2350.     DView            * super;
  2351.     DEditText    * et;
  2352.     DPrompt        * pr;
  2353.     DCheckBox    * ck;
  2354.     DPopupList* pop;
  2355.     Nlm_FonT    promptFont = Nlm_programFont; //Nlm_systemFont
  2356.     Nlm_FonT    editFont = Nlm_programFont; 
  2357.     short         listitem;
  2358.     char        * name;
  2359.  
  2360.  
  2361.     fView= new DGopherEditView(citem, this, fGopher, fURL, 50, 20, true, NULL);
  2362.     super= fView;
  2363.     
  2364.     pr= new DPrompt(0, super, "Protocol:", 0, 0, promptFont);             
  2365.     super->NextSubviewToRight();
  2366.     pop= new DPopupList(cProto, super, true);
  2367.     listitem= 0;
  2368.     do {
  2369.       name= (char*)DGopher::GetProtoName( listitem);
  2370.     if (name) {
  2371.             pop->AddItem( name);
  2372.             if (!DGopher::GetProtoSupport(listitem)) 
  2373.                 pop->SetItemStatus( listitem+1, false);
  2374.             listitem++;
  2375.             }
  2376.     } while (name);
  2377.     super->NextSubviewBelowLeft();
  2378.  
  2379.     pr= new DPrompt(0, super, "Name:", 0, 0, promptFont);             
  2380.     super->NextSubviewToRight();
  2381.     et= new DEditText(cTITL, super, (char*)fName, 30, editFont);
  2382.     this->SetEditText(et);
  2383.     super->NextSubviewBelowLeft();
  2384.     
  2385.     pr= new DPrompt(0, super, "Host:", 0, 0, promptFont);             
  2386.     super->NextSubviewToRight();
  2387.     et= new DEditText(cHOST, super, (char*)fHost, 30, editFont);
  2388.     this->SetEditText(et);
  2389.     super->NextSubviewBelowLeft();
  2390.  
  2391.     if (fEditAll) {
  2392.         pr= new DPrompt(0, super, "Path:", 0, 0, promptFont);             
  2393.         super->NextSubviewToRight();
  2394.         et= new DEditText(cPATH, super, (char*)fPath, 30, editFont);
  2395.         this->SetEditText(et);
  2396.         super->NextSubviewBelowLeft();
  2397.         
  2398.         pr= new DPrompt(0, super, "Type:", 0, 0, promptFont);             
  2399.         super->NextSubviewToRight();
  2400.         pop= new DPopupList(cKIND, super, true);
  2401.  
  2402. #if 1        
  2403.         listitem= 0;
  2404.         do {
  2405.           name= (char*)DGopher::GetTypeName( listitem);
  2406.       if (name) {
  2407.                 pop->AddItem( name);
  2408.                 if (!DGopher::GetTypeSupport(listitem)) 
  2409.                     pop->SetItemStatus( listitem+1, false);
  2410.                 listitem++;
  2411.                 }
  2412.         } while (name);
  2413.  
  2414. #else
  2415.                     // AARRRRGGGHHHHH !!!!!!!!
  2416.                     // there should be DGopher STATIC method(s) 
  2417.                     // to return gopher class list/name/item#
  2418.                     // so we can add/change classes w/o having to edit unrelated files like this one !
  2419.         pop->AddItem("Document");     
  2420.         pop->AddItem("Folder");     
  2421.         pop->AddItem("Query");     
  2422.         pop->AddItem("Binary file");     
  2423.         pop->AddItem("Image");     
  2424.         pop->AddItem("Sound");     
  2425.         pop->AddItem("Movie");     
  2426.         pop->AddItem("Note");     
  2427.         pop->AddItem("Html");     
  2428.         pop->AddItem("Mailto");     
  2429.         pop->AddItem("Telnet link");     
  2430.         pop->AddItem("TN3270 link");     
  2431.         ///
  2432.         pop->AddItem("CSO Phonebook");     
  2433.         pop->AddItem("Whois Phonebook");     
  2434.         pop->AddItem("Binhex file");     
  2435.         pop->AddItem("Uuencoded file");     
  2436.  
  2437.         pop->AddItem("Unknown type");     
  2438. #endif
  2439.         super->NextSubviewToRight();
  2440.  
  2441.         ck= new DCheckBox(ctran, super, "Use binary transfer");
  2442.         ck->SetStatus(false);
  2443.         super->NextSubviewBelowLeft();
  2444.         }
  2445.     
  2446.     pr= new DPrompt(0, super, "Port:", 0, 0, promptFont);             
  2447.     super->NextSubviewToRight();
  2448.     et= new DEditText(cPORT, super, (char*)fPort, 4, editFont);
  2449.     this->SetEditText(et);
  2450.     super->NextSubviewToRight();
  2451.  
  2452.         // ?? make new method  DView::NextSubviewOffset( x, y);
  2453.         // ?? make new method  DView::NextSubviewMoveto( x, y);
  2454.     Nlm_PoinT nps;
  2455.     super->GetNextPosition( &nps);
  2456.     nps.x += 15; 
  2457.     super->SetNextPosition( nps);
  2458.  
  2459.     ck= new DCheckBox(cisGp, super, "Is Gopher+ link");
  2460.     ck->SetStatus(false);
  2461.     super->NextSubviewBelowLeft();
  2462.  
  2463.     pr= new DPrompt(0, super, " -- or enter universal resource locator -- ",
  2464.              0, 0, promptFont);             
  2465.     super->NextSubviewBelowLeft();
  2466.  
  2467.     pr= new DPrompt(0, super, "URL:", 0, 0, promptFont);             
  2468.     super->NextSubviewToRight();
  2469.     et= new DEditText(cURL, super, (char*)fURL, 60, editFont);
  2470.     this->SetEditText(et);
  2471.     super->NextSubviewBelowLeft();
  2472.  
  2473.     this->AddOkayCancelButtons();
  2474.     fView->InstallControls();
  2475.     
  2476.     DWindow::Open();
  2477. }
  2478.  
  2479.  
  2480.  
  2481. // DGopherEditView ------------------------
  2482.  
  2483.  
  2484. DGopherEditView::DGopherEditView(long id, DView* itsSuperior, DGopher* itsGopher,
  2485.             const char* oldURL, short width, short height, Boolean hidden, char* title) :
  2486.     DCluster( id, itsSuperior, width, height, hidden, title),
  2487.     fOldURL(NULL), fGopher(itsGopher)
  2488. {
  2489.     fOldURL= StrDup( (char*) oldURL);
  2490. }
  2491.  
  2492. DGopherEditView::~DGopherEditView()
  2493. {
  2494.     MemFree( fOldURL);
  2495. }
  2496.  
  2497. void    DGopherEditView::InstallControls()
  2498. {
  2499.     DControl* nextline= this;
  2500.     DGopher*  go= fGopher;
  2501.  
  2502.     if (go) {
  2503.         DEditText * et;
  2504.         DEditText * nt; //DNumberText
  2505.         DCheckBox * cb;
  2506.         DPopupList * pop;
  2507.         DButton   * bt;
  2508.         char         aLine[256];
  2509.         short            item;
  2510.         
  2511. #define go2EditText(ID, GOVAL)        \
  2512. { if (NULL != (et= (DEditText*)nextline->FindSubview(ID))) \
  2513.     et->SetTitle( (char*)GOVAL); }
  2514.  
  2515. #define go2NumbText(ID, GOVAL)        \
  2516. { if (NULL != (nt= (DEditText*)nextline->FindSubview(ID))) \
  2517.     sprintf(aLine, "%d", GOVAL); nt->SetTitle( aLine); }
  2518.  
  2519. #define go2CheckBox(ID, GOVAL)        \
  2520. { if (NULL != (cb= (DCheckBox*)nextline->FindSubview(ID))) \
  2521.     cb->SetStatus( GOVAL ); }
  2522.  
  2523. #define go2Popup(ID, GOVAL)        \
  2524. { if (NULL != (pop= (DPopupList*)nextline->FindSubview(ID))) \
  2525.     pop->SetValue( GOVAL ); }
  2526.  
  2527.         item= 1 + DGopher::GetProtoItem( go->fProtocol);
  2528.         go2Popup( cProto, item);
  2529.  
  2530.         go2EditText( cTITL, go->GetName());
  2531.         go2EditText( cHOST, go->GetHost());
  2532.         go2EditText( cPATH, go->GetPath());
  2533.         go2EditText( cPORT, go->GetPort());
  2534.         go2EditText( cURL, go->GetURL());
  2535.  
  2536. #if 1
  2537.         item= 1 + DGopher::GetTypeItem( go->fType);
  2538. #else
  2539.         switch (go->fType) {
  2540.         
  2541.                     // AARRRRGGGHHHHH !!!!!!!!
  2542.                     // there should be DGopher STATIC method(s) 
  2543.                     // to return gopher class list/name/item#
  2544.                     // so we can add/change classes w/o having to edit unrelated files like this one !
  2545.  
  2546.             case kTypeFile           : item= 1; break;
  2547.             case kTypeFolder        : item= 2; break;
  2548.             case kTypeQuery        : item= 3; break;
  2549.             case kTypeBinary       : item= 4; break;
  2550.             case kTypeImage            : item= 5; break;
  2551.             case kTypeGif                : item= 5; break; // kTypeImage
  2552.             case kTypeSound       : item= 6; break;
  2553.             case kTypeMovie            : item= 7; break;
  2554.             case kTypeNote            : item= 8; break;
  2555.  
  2556.             case kTypeHtml            : item= 9; break;
  2557.             case kMailType            : item= 10; break;
  2558.             case kTypeTelnet       : item= 11; break;
  2559.             case kTypeTn3270        : item= 12; break; // ?? or kTypeTelnet
  2560.             case kTypeMime            : item= 1; break;
  2561.  
  2562.             case kTypeCSO              : item= 13; break;
  2563.             case kTypeWhois          : item= 14; break;
  2564.             case kTypeBinhex      : item= 15; break;
  2565.             case kTypeUuencode  : item= 16; break;
  2566.  
  2567.             default                            : item= 17; break;
  2568.             }
  2569. #endif
  2570.         go2Popup( cKIND, item);
  2571.             
  2572.         go2CheckBox( ctran, go->fTransferType == kTransferBinary);
  2573.         go2CheckBox( cisGp, go->fIsPlus == kGopherPlusYes);
  2574.  
  2575.         go2EditText( ctype, Idtype2Str( go->fMacType));
  2576.         go2EditText( csire, Idtype2Str( go->fMacSire));
  2577.         //go2Button( cappn, GetComment);
  2578.  
  2579. #undef go2Popup            
  2580. #undef go2CheckBox
  2581. #undef go2NumbText
  2582. #undef go2EditText            
  2583.         }
  2584. }
  2585.  
  2586.  
  2587.     
  2588. void    DGopherEditView::Answers()
  2589. {
  2590.     DControl* cline= this;
  2591.     DGopher*  go= fGopher;
  2592.     
  2593.     if (cline && go) {
  2594.         DEditText * et;
  2595.         DEditText * nt;
  2596.         DCheckBox * cb;
  2597.         DPopupList * pop;
  2598.         DButton   * bt;
  2599.         char             aLine[256];
  2600.         short            item;
  2601.             
  2602. #define EditText2Go(ID, MAPFUNC)        \
  2603.     if (NULL != (et= (DEditText*)cline->FindSubview(ID))) \
  2604.         { et->GetTitle( aLine, 256); go->MAPFUNC(aLine); }
  2605.                 
  2606. #define EditText2Golong(ID, VAR)        \
  2607.     if (NULL != (et= (DEditText*)cline->FindSubview(ID))) \
  2608.         { et->GetTitle( aLine, 256); VAR = Str2Idtype(aLine); }
  2609.  
  2610. #define CheckBox2Go(ID, MAPFUNC)        \
  2611.     if (NULL != (cb= (DCheckBox*)cline->FindSubview(ID))) \
  2612.       { go->MAPFUNC(cb->GetStatus()); }
  2613.  
  2614.         if (NULL != (pop= (DPopupList*)cline->FindSubview(cProto)))
  2615.             go->fProtocol= DGopher::GetProtoVal(pop->GetValue()-1);
  2616.  
  2617.         EditText2Go( cTITL, StoreName);
  2618.         EditText2Go( cPATH, StorePath);
  2619.         EditText2Go( cHOST, StoreHost);
  2620.         EditText2Go( cPORT, StorePort);
  2621.         CheckBox2Go( cisGp, StorePlus);
  2622.  
  2623.         EditText2Golong( ctype, go->fMacType);
  2624.         EditText2Golong( csire, go->fMacSire);
  2625.         if (NULL != (cb= (DCheckBox*)cline->FindSubview(ctran)))  {
  2626.             if (cb->GetStatus()) go->fTransferType= kTransferBinary;
  2627.             else go->fTransferType= kTransferText;
  2628.             }
  2629.  
  2630.         if (NULL != (pop= (DPopupList*)cline->FindSubview(cKIND)))
  2631. #if 1
  2632.             go->fType= DGopher::GetTypeVal(pop->GetValue()-1);
  2633. #else
  2634.             switch (pop->GetValue()) {
  2635.                 case  1: go->fType= kTypeFile; break;
  2636.                 case  2: go->fType= kTypeFolder; break;
  2637.                 case  3: go->fType= kTypeQuery; break;
  2638.                 case  4: go->fType= kTypeBinary; break;
  2639.                 case  5: go->fType= kTypeImage; break;
  2640.                 case  6: go->fType= kTypeSound; break;
  2641.                 case  7: go->fType= kTypeMovie; break;
  2642.                 case  8: go->fType= kTypeNote; break;
  2643.                 case  9: go->fType= kTypeHtml; break;
  2644.                 case 10: go->fType= kMailType; break;
  2645.                 case 11: go->fType= kTypeTelnet; break;
  2646.                 case 12: go->fType= kTypeTn3270; break;
  2647.  
  2648.                 case 13: go->fType= kTypeCSO; break;
  2649.                 case 14: go->fType= kTypeWhois; break;
  2650.                 case 15: go->fType= kTypeBinhex; break;
  2651.                 case 16: go->fType= kTypeUuencode; break;
  2652.  
  2653.                 default:
  2654.                 case 17: go->fType= kTypeError; break; 
  2655.                 }
  2656. #endif
  2657.  
  2658.                 // check URL last ?? so it can override other opts ??
  2659.         //EditText2Go( cURL, StoreURL);  
  2660.         if (NULL != (et= (DEditText*)cline->FindSubview(cURL))) { 
  2661.             char     aURL[512];
  2662.             et->GetTitle( aURL, 512); 
  2663.             long urllen= StrLen( aURL);
  2664.             if ( urllen < 5 || StrCmp( aURL, fOldURL) == 0 ) 
  2665.                 go->StoreURL( NULL);
  2666.             else {
  2667.                 // go->StoreURL( aURL); // redundant
  2668.                 DGopher* newgo= DGopherList::GopherFromURL( aURL, urllen, NULL, false);
  2669.                 go->CopyGopher(newgo);
  2670.                 }
  2671.             }
  2672.                 
  2673.  
  2674. #undef EditText2Go                            
  2675. #undef CheckBox2Go                            
  2676. #undef EditText2Golong                            
  2677.          }
  2678. }
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691. // DGoMapEditDlog ------------------------
  2692.  
  2693.  
  2694. enum DGoMapEditCmds {
  2695.     cHandID = 512, cGoplusKind,cHandType,cHandName,cHandSig,cTrans,cPref,
  2696.     cLocalType,cServerType,cListOld,
  2697.     cServerSuffixes
  2698.     };
  2699.  
  2700.  
  2701. DGoMapEditDlog::DGoMapEditDlog(DGopherMap* itsMapper, short itsForm, char* itsKind) :
  2702.     DWindow( 0, NULL, DWindow::fixed, -10, -10, -50, -20, NULL, kDontFreeOnClose),
  2703.     fView(NULL), fOtherKinds(NULL),
  2704.     fForm(itsForm),
  2705.     fMapper(itsMapper), fNewMapper(NULL)
  2706. {    
  2707.     if (fMapper) {
  2708.         //fMapper->newOwner(); //??
  2709.         //fForm= itsForm;
  2710.         switch (fForm) {
  2711.             case kFormLocal: this->SetTitle("Edit document type handler"); break;
  2712.             case kFormServerSuffixes: this->SetTitle("Edit server suffix mapping"); break;
  2713.             case kFormServerLocalMap: this->SetTitle("Edit server-local type mapping"); break;
  2714.             }
  2715.         }
  2716.     else {
  2717.         fForm= kFormNew; //kFormLocal;
  2718.         fNewMapper= new DGopherMap();  
  2719.         fMapper= fNewMapper;
  2720.         //fMapper->newOwner(); //??
  2721.         fMapper->fStatus= kAdded;
  2722.         this->SetTitle("New document type handler");
  2723.             // this one will trash current text handler ??
  2724.         //fMapper->SetHandlerType("Internal");
  2725.         //fMapper->SetID( gInternalHandlerIDs[kTextHandler]); // ??  if Internal, must be valid !?
  2726.         fMapper->SetHandlerType("External");
  2727.         fMapper->SetID( "abcd"); 
  2728.             // ??  if Internal, must be valid !?
  2729.         fMapper->SetKind( itsKind);
  2730.         fMapper->SetHandlerName("Application name");
  2731.         fMapper->SetPreference("1");
  2732.         fMapper->SetServerType("0");
  2733.         fMapper->SetLocalType("0");
  2734.         fMapper->SetSuffix(".txt");
  2735.         fMapper->SetMacTypeNSire("TEXT/ttxt");
  2736.         fMapper->SetServerSuffixes(".txt");
  2737.         fMapper->SetTransferBinary();
  2738.         }
  2739. }
  2740.  
  2741. DGoMapEditDlog::~DGoMapEditDlog()
  2742. {
  2743.     //if (fView) delete fView; //!!!!! NOOOOOOO we delete all subviews now !!!!!
  2744.     if (fNewMapper) fNewMapper->suicide();
  2745.     MemFree( fOtherKinds);
  2746. }
  2747.  
  2748. void DGoMapEditDlog::OkayAction()
  2749. {
  2750.     fView->Answers();
  2751.     if (fForm == kFormNew && fOtherKinds)  
  2752.         fMapper->SetKind( fOtherKinds);
  2753.     if (fMapper->fStatus == kNochange) 
  2754.         fMapper->fStatus= kChanged;
  2755. }
  2756.  
  2757. Boolean DGoMapEditDlog::IsMyAction( DTaskMaster* action) 
  2758. {    
  2759.     switch (action->Id()) {
  2760.  
  2761.         case cListOld: {
  2762.             DGopherMap * mp= NULL;
  2763.             DPopupList * pop = (DPopupList*) action;
  2764.             short val= pop->GetValue()-1;
  2765.             if (val) mp= gGopherMap->GopherMapAt( val-1); // -1 ??????
  2766.             else mp= fNewMapper;
  2767.             if (mp) {
  2768.                 // !!!! MUST Fiddle w/ mapper::fKind so that caller's original itsKind isn't trashed
  2769.                 char    buf[512];
  2770.                 mp->fKind->GetAllNames( buf, sizeof(buf));
  2771.                 if (fOtherKinds) MemFree(fOtherKinds);
  2772.                 fOtherKinds= StrDup( buf);
  2773.                 
  2774.                 //fMapper->suicide(); //??
  2775.                 fMapper= mp;
  2776.                 //fMapper->newOwner(); //??
  2777.                 fMapper->fStatus= kNochange;
  2778.                 fView->fMapper= fMapper;
  2779.                 fView->fInstallKind= false;
  2780.                 fView->InstallControls();
  2781.                 }
  2782.             return true;
  2783.             }
  2784.  
  2785.         default:
  2786.             return DWindow::IsMyAction(action);
  2787.         }
  2788. }
  2789.  
  2790. void DGoMapEditDlog::Open()
  2791. {
  2792.     DView* super;
  2793.     DEditText* et;
  2794.     DPrompt* pr;
  2795.     DCheckBox* ck;
  2796.     DPopupList* pop;
  2797.     Nlm_FonT    promptFont = Nlm_programFont; //Nlm_systemFont;
  2798.     Nlm_FonT    editFont = Nlm_programFont;
  2799.     Boolean        doListOld;
  2800.     
  2801.     doListOld= (fForm == kFormNew);
  2802.     //if (doListOld) fForm= kFormLocal;
  2803.     fView= new DGoMapEditView(0, this, fForm, fMapper, 50, 20, true, NULL);
  2804.     super= fView;
  2805.  
  2806.     pr= new DPrompt(0, super, "Document Kind:", 0, 0, promptFont);             
  2807.     super->NextSubviewToRight();
  2808.     et= new DEditText(cGoplusKind, super, "", 30, editFont);
  2809.     this->SetEditText(et);
  2810.     super->NextSubviewBelowLeft();
  2811.     
  2812.     if (doListOld) {
  2813.         pr= new DPrompt(0, super, "Handle as this kind:", 0, 0, promptFont);             
  2814.         super->NextSubviewToRight();
  2815.         pop= new DPopupList(cListOld, super, true);
  2816.         long i, n= gGopherMap->GetSize();
  2817.         pop->AddItem("New local kind");    
  2818.         for (i=0;i<n;i++) { 
  2819.             DGopherMap* mp= gGopherMap->GopherMapAt(i); 
  2820.             pop->AddItem((char*)mp->GetKind());    
  2821.             } 
  2822.         super->NextSubviewBelowLeft(); 
  2823.         
  2824.         }
  2825.         
  2826.     if (fForm == kFormLocal || fForm == kFormNew) {
  2827.         DCluster* clu= new DCluster( 0, super, 0, 0, false,"Edit local handler values");
  2828.         //clu->SetResize( DView::moveinsuper, DView::moveinsuper);
  2829.         super= clu;  
  2830.         pr= new DPrompt(0, super, "Local ID:", 0, 0, promptFont);             
  2831.         super->NextSubviewToRight();
  2832.         et= new DEditText(cHandID, super, "", 5, editFont);
  2833.         this->SetEditText(et);
  2834.         super->NextSubviewBelowLeft(); //NextSubviewToRight();
  2835.  
  2836.         pr= new DPrompt(0, super, "Preference for this kind:", 0, 0, promptFont);             
  2837.         super->NextSubviewToRight();
  2838.         et= new DEditText(cPref, super, "", 8, editFont);
  2839.         super->NextSubviewBelowLeft();
  2840.         
  2841.         ck= new DCheckBox(cTrans, super, "Use binary transfer");
  2842.         ck->SetStatus(true);
  2843.         super->NextSubviewBelowLeft();
  2844.  
  2845.         pr= new DPrompt(0, super, "Handler Type:", 0, 0, promptFont);             
  2846.         super->NextSubviewToRight();
  2847.         pop= new DPopupList(cHandType, super, true);
  2848.         pop->AddItem("External");     
  2849.         pop->AddItem("Internal");     
  2850.         pop->AddItem("None");     
  2851.         super->NextSubviewBelowLeft(); 
  2852.     
  2853.         
  2854.         pr= new DPrompt(0, super, " For External handlers ----------", 0, 0, promptFont);             
  2855.         super->NextSubviewBelowLeft();
  2856.          
  2857.         // Button for user file/appl get dialog...
  2858.         
  2859.         pr= new DPrompt(0, super, "Handler App:", 0, 0, promptFont);             
  2860.         super->NextSubviewToRight();
  2861.         et= new DEditText(cHandName, super, "", 30, editFont);
  2862.         this->SetEditText(et);
  2863.         super->NextSubviewBelowLeft();
  2864.     
  2865.     #ifdef WIN_MAC
  2866.         pr= new DPrompt(0, super, "File signature:", 0, 0, promptFont);             
  2867.     #else
  2868.         pr= new DPrompt(0, super, "File suffix:", 0, 0, promptFont);             
  2869.     #endif
  2870.         super->NextSubviewToRight();
  2871.         et= new DEditText(cHandSig, super, "", 9, editFont);
  2872.         this->SetEditText(et);
  2873.         super->NextSubviewBelowLeft();
  2874.         }
  2875.     
  2876.     else if (fForm == kFormServerSuffixes) {
  2877.         //pr= new DPrompt(0, super, "--- Mapping from server to local types ---", 0, 0, promptFont);             
  2878.         //super->NextSubviewBelowLeft();
  2879.     
  2880.         pr= new DPrompt(0, super, "Server suffixes to map:", 0, 0, promptFont);             
  2881.         super->NextSubviewToRight();
  2882.         et= new DEditText(cServerSuffixes, super, "", 20, editFont);
  2883.         this->SetEditText(et);
  2884.         }
  2885.         
  2886.     else if (fForm == kFormServerLocalMap) {
  2887.         //pr= new DPrompt(0, super, "--- Mapping from server to local types ---", 0, 0, promptFont);             
  2888.         //super->NextSubviewBelowLeft();
  2889.  
  2890.         pr= new DPrompt(0, super, "Server Gopher0 type to map:", 0, 0, promptFont);             
  2891.         super->NextSubviewToRight();
  2892.         et= new DEditText(cServerType, super, "", 2, editFont);
  2893.         super->NextSubviewBelowLeft();
  2894.         
  2895.         pr= new DPrompt(0, super, "to Local Gopher0 Type:", 0, 0, promptFont);             
  2896.         super->NextSubviewToRight();
  2897.         et= new DEditText(cLocalType, super, "", 2, editFont);
  2898.         this->SetEditText(et);
  2899.         super->NextSubviewBelowLeft();
  2900.         }
  2901.     
  2902.     this->AddOkayCancelButtons();
  2903.     fView->InstallControls();
  2904.     
  2905.     DWindow::Open();
  2906. }
  2907.  
  2908.  
  2909.  
  2910. // DGoMapEditView ------------------------
  2911.  
  2912. DGoMapEditView::DGoMapEditView(long id, DView* itsSuperior, short itsForm, DGopherMap* itsMapper,
  2913.             short width, short height, Boolean hidden, char* title) :
  2914.     DCluster( id, itsSuperior, width, height, hidden, title),
  2915.     fForm(itsForm), fInstallKind(true),
  2916.     fMapper(itsMapper)
  2917. {
  2918. }
  2919.  
  2920.  
  2921. DGoMapEditView::~DGoMapEditView()
  2922. {
  2923. }
  2924.  
  2925.  
  2926. void    DGoMapEditView::InstallControls()
  2927. {
  2928.     DControl* nextline= this;
  2929.     DGopherMap*  go= fMapper;
  2930.  
  2931.     if (go) {
  2932.         DEditText * et;
  2933.         DEditText * nt; //DNumberText
  2934.         DCheckBox * cb;
  2935.         DPopupList * pop;
  2936.         DButton   * bt;
  2937.         char         aLine[256];
  2938.         short            item;
  2939.         
  2940. #define go2EditText(ID, GOVAL)        \
  2941. { if (NULL != (et= (DEditText*)nextline->FindSubview(ID))) \
  2942.     et->SetTitle( (char*)GOVAL); }
  2943.  
  2944. #define go2NumbText(ID, GOVAL)        \
  2945. { if (NULL != (nt= (DEditText*)nextline->FindSubview(ID))) \
  2946.     sprintf(aLine, "%d", GOVAL); nt->SetTitle( aLine); }
  2947.  
  2948. #define go2CheckBox(ID, GOVAL)        \
  2949. { if (NULL != (cb= (DCheckBox*)nextline->FindSubview(ID))) \
  2950.     cb->SetStatus( GOVAL ); }
  2951.  
  2952. #define go2Popup(ID, GOVAL)        \
  2953. { if (NULL != (pop= (DPopupList*)nextline->FindSubview(ID))) \
  2954.     pop->SetValue( GOVAL ); }
  2955.  
  2956.     if (fInstallKind) go2EditText( cGoplusKind, go->GetKind());
  2957.     if (fForm != DGoMapEditDlog::kFormLocal
  2958.           && NULL != (et= (DEditText*)nextline->FindSubview(cGoplusKind))) 
  2959.               et->Disable();
  2960.               
  2961.     if (fForm == DGoMapEditDlog::kFormLocal ||
  2962.           fForm == DGoMapEditDlog::kFormNew) {
  2963.         go2EditText( cHandID, go->GetID());  
  2964.         go2EditText( cHandName, go->GetHandlerName());
  2965.         go2EditText( cPref, go->GetPreference());
  2966.         go2EditText( cHandSig, go->GetSuffix());
  2967.         
  2968.         switch (*(go->GetHandlerType())) {
  2969.             case 'L'    :
  2970.             case 'l'    :
  2971.             case 'e'    :
  2972.             case 'E'    : item= 1; break;
  2973.             case 'i'    :
  2974.             case 'I'    : item= 2; break;
  2975.             case 'n'    :
  2976.             case 'N'    : item= 3; break;
  2977.             default        : item= 1; break;
  2978.             }
  2979.         go2Popup( cHandType, item);
  2980.         go2CheckBox( cTrans, go->GetTransferBinary());
  2981.         }
  2982.     
  2983.     else if (fForm == DGoMapEditDlog::kFormServerSuffixes) {
  2984.         go2EditText( cServerSuffixes, go->GetServerSuffixes());
  2985.         }
  2986.     else if (fForm == DGoMapEditDlog::kFormServerLocalMap) {
  2987.         go2EditText( cServerType, go->GetServerType());
  2988.         go2EditText( cLocalType, go->GetLocalType());
  2989.         }
  2990.  
  2991. #undef go2Popup            
  2992. #undef go2CheckBox
  2993. #undef go2NumbText
  2994. #undef go2EditText            
  2995.         }
  2996. }
  2997.  
  2998.  
  2999.     
  3000. void    DGoMapEditView::Answers()
  3001. {
  3002.     DControl* cline= this;
  3003.     DGopherMap*  go= fMapper;
  3004.     
  3005.     if (cline && go) {
  3006.         DEditText * et;
  3007.         DEditText * nt;
  3008.         DCheckBox * cb;
  3009.         DPopupList * pop;
  3010.         DButton   * bt;
  3011.         char             aLine[256];
  3012.         short            item;
  3013.             
  3014. #define EditText2Go(ID, MAPFUNC)        \
  3015.     if (NULL != (et= (DEditText*)cline->FindSubview(ID))) \
  3016.         { et->GetTitle( aLine, 256); go->MAPFUNC(aLine); }
  3017.                 
  3018. #define EditText2Golong(ID, VAR)        \
  3019.     if (NULL != (et= (DEditText*)cline->FindSubview(ID))) \
  3020.         { et->GetTitle( aLine, 256); VAR = Str2Idtype(aLine); }
  3021.  
  3022. #define CheckBox2Go(ID, MAPFUNC)        \
  3023.     if (NULL != (cb= (DCheckBox*)cline->FindSubview(ID))) \
  3024.       { go->MAPFUNC(cb->GetStatus()); }
  3025.  
  3026.     if (fForm == DGoMapEditDlog::kFormLocal 
  3027.         || fForm == DGoMapEditDlog::kFormNew) {
  3028.         //if (go->fKind) { MemFree(go->fKind); go->fKind= NULL; } // SetKind bug, sets alt kind if fKind !
  3029.         EditText2Go( cGoplusKind, SetKind);
  3030.         EditText2Go( cHandID, SetID);
  3031.         EditText2Go( cHandName, SetHandlerName);
  3032.         EditText2Go( cPref, SetPreference);
  3033.         EditText2Go( cHandSig, SetSuffix);
  3034.         CheckBox2Go( cTrans, SetTransferBinary);
  3035.  
  3036.         if (NULL != (pop= (DPopupList*)cline->FindSubview(cHandType)))
  3037.             switch (pop->GetValue()) {
  3038.                 case  1: go->SetHandlerType("External"); break;
  3039.                 case  2: go->SetHandlerType("Internal"); break;
  3040.                 default:
  3041.                 case  3: go->SetHandlerType("None"); break;
  3042.                 }
  3043.         }            
  3044.     else if (fForm == DGoMapEditDlog::kFormServerSuffixes) {
  3045.         EditText2Go( cServerSuffixes, SetServerSuffixes);
  3046.         }
  3047.     else if (fForm == DGoMapEditDlog::kFormServerLocalMap) {
  3048.         EditText2Go( cServerType, SetServerType);
  3049.         EditText2Go( cLocalType, SetLocalType);
  3050.         }
  3051.         
  3052. #undef EditText2Go                            
  3053. #undef CheckBox2Go                            
  3054. #undef EditText2Golong                            
  3055.          }
  3056. }
  3057.  
  3058.  
  3059.